XC8: .asm to C ( i.e. Lowering One's Expectations)

WBahn

Joined Mar 31, 2012
32,925
No one is.

Except for trivial snippets, C is incapable of producing code, either size or speed, close to that which a good .asm programmer can write.

My WAG at this point: the best C programmer (with time heavily invested in researching and memorizing the best writing approach and code structure) is probable 2:1 worse than the best .asm programmer.

And it only gets worse from there.
Why should this be in the least bit surprising or unexpected?

It's like choosing to buy a rebuilt engine from someplace like Jasper and then complaining that you don't get the same performance out of it as you could get from a shop that does custom rebuilds to spec. Hardly a surprise.

If nothing else, most C compilers (I have no idea about XC8) are based on some kind of stack-oriented virtual machine abstraction. There are performance penalties that go along with that. If your project can't tolerate those penalties, then don't use C (or nearly any other HLL).
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
Why should this be in the least bit surprising or unexpected?
It's not, and it never was (although I've had plenty of arguments with some here in the peanut gallery who insist C can compile into better code than one can write in .asm -- ha!).

It's why I've had to be dragged -- kicking and screaming -- into C on 8 bit platforms.

This is an adventure I never wanted to have, and one I'd successfully avoided it up until the past year or so. The necessity was caused by Microchip's unwillingness to continue to support .asm development for the newer, more capable PIC products.

My productivity level has dropped precipitously. Not because of my lack of knowledge of C, but because I've had to rewrite an entire set of libraries developed and tested over 35 years.

Simultaneously, I've had to discover all the code constructs that are necessary to write the best streamlined code (for 8 bit parts). This is not something the ordinary software developer concerns himself with, and I am not an ordinary developer.
 

WBahn

Joined Mar 31, 2012
32,925
It's not, and it never was (although I've had plenty of arguments with some here in the peanut gallery who insist C can compile into better code than one can write in .asm -- ha!).
I'm not aware of anyone that claims that C can compile into better code than ANYONE can write in assembly.

Anyone making such a statement is almost certainly talking in broad generalities that are properly interpreted as meaning that the better C compilers can compile to better code than MOST people can write in assembly, and that is almost certainly a true statement. It is almost certainly also a true statement that the better assembly language programmers can produce code that is better than (or at least as good as) ANY C compiler can produce. There is no guarantee that that will always be the case, but I would be willing to bet my life savings on it being true for at least the next couple centuries.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
I'm not aware of anyone that claims that C can compile into better code than ANYONE can write in assembly.
Then you haven't been following my threads going back at least 10 years, if not further.

As for the rest of your comment, you've proven a modicum of common sense, a rare quality not shared by some who respond to my rants.

The bottom line is as follows:

1. I greatly enjoy coding in .asm.

2. I am good at it, and can do things most programmers cannot do in any language, on a given piece of hardware.

3. This makes me competitive in my market. I make a pretty good living doing it.

4. I resent being forced to adopt C by my hardware vendor of choice, especially when the chips themselves seem not to have a problem running code written in .asm (that's a joke).

5. I like to bitch about things I resent, especially among those who understand what I'm bitching about, even though they may not agree with me -- and get annoyed by my continuous bellyaching.

6. And I especially hate looking at the vomit spewed forth by the compiler at compile time.

Regardless, here I am and this saga will continue.
 
Last edited:

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
Btw, I've completed the driver code today for the RNBD451.

It's pretty impressive, even considering it's written in C.

Completely self-contained, self-configuring and non-blocking (at the character level*), it plays real nice with the other dozen device drivers and app routines that are running concurrently.

The final bug was solved by running down an undocumented response to the radio losing connection from out-of-range.

I'd love to share the code, but I'm keeping this one to myself.

(*And by this I mean it runs full speed with only a 2 character receive buffer under full CPU load. )
 
Last edited:

ApacheKid

Joined Jan 12, 2015
1,762
It's not, and it never was (although I've had plenty of arguments with some here in the peanut gallery who insist C can compile into better code than one can write in .asm -- ha!).

It's why I've had to be dragged -- kicking and screaming -- into C on 8 bit platforms.

This is an adventure I never wanted to have, and one I'd successfully avoided it up until the past year or so. The necessity was caused by Microchip's unwillingness to continue to support .asm development for the newer, more capable PIC products.

My productivity level has dropped precipitously. Not because of my lack of knowledge of C, but because I've had to rewrite an entire set of libraries developed and tested over 35 years.

Simultaneously, I've had to discover all the code constructs that are necessary to write the best streamlined code (for 8 bit parts). This is not something the ordinary software developer concerns himself with, and I am not an ordinary developer.
As others have said, welcome to capitalism. I asked you much are you prepared to pay for an assembler, well how much?
 

nsaspook

Joined Aug 27, 2009
16,340
Then you haven't been following my threads going back at least 10 years, if not further.

As for the rest of your comment, you've proven a modicum of common sense, a rare quality not shared by some who respond to my rants.

The bottom line is as follows:

1. I greatly enjoy coding in .asm.

2. I am good at it, and can do things most programmers cannot do in any language, on a given piece of hardware.

3. This makes me competitive in my market. I make a pretty good living doing it.

4. I resent being forced to adopt C by my hardware vendor of choice, especially when the chips themselves seem not to have a problem running code written in .asm (that's a joke).

5. I like to bitch about things I resent, especially among those who understand what I'm bitching about, even though they may not agree with me -- and get annoyed by my continuous bellyaching.

6. And I especially hate looking at the vomit spewed forth by the compiler at compile time.

Regardless, here I am and this saga will continue.
Old navy saying. A bitching sailor is a happy sailor. A bitching sailor still cares about the job.

I see a great future in you as a C programmer, after a few more projects..
 
Last edited:

ApacheKid

Joined Jan 12, 2015
1,762
7. I imagine there's a Microchip executive following this thread, and that these posts will eventually convince him to resurrect mpasm on MPLabX.
Do you expect an assembler to be free? I can write one for you, how much are willing to pay for something like that?
 

nsaspook

Joined Aug 27, 2009
16,340
7. I imagine there's a Microchip executive following this thread, and that these posts will eventually convince him to resurrect mpasm on MPLabX.
You make a funny.

https://forum.allaboutcircuits.com/...s-it-was-great-to-know-ya.171736/post-1537063
MPASM will not be updated to run on 64-bit platforms. An ENORMOUS blunder IMO on so many levels.

https://forum.allaboutcircuits.com/...owering-ones-expectations.190219/post-1802867
... a vast project with half-vast ideas. ;)
IMO, the corporate response today is, no support for multiple tool chains and no release of private internal tool chain source code for programs to the public.

Nothing has changed.


A little happy C news. A 'Great' C programmer uses the hammer on those that don't really understand the requirements and uses of embedded C.

https://www.phoronix.com/news/Torvalds-Arithmetic-Overflows
Kees Cook with Google has been working on figuring out how to better deal with unexpected arithmetic overflow bugs within the Linux kernel's C source code. He's hoping to see a systematic way for the Linux kernel to be able to deal with such arithmetic overflow/underflow/wrap-around problems. Among the initial thinking is to better engage compiler-based sanitizers or a recent C language proposal for operator overloading without name mangling. In the latter proposal as a potential solution, C operator overloading could allow for arbitrary handling of overflows within the helpers.
https://lore.kernel.org/lkml/CAHk-=wi5YPwWA8f5RAf_Hi8iL0NhGJeL6MN6UFWwRMY8L6UDvQ@mail.gmail.com/
I'm still entirely unconvinced.

The thing is, wrap-around is not only well-defined, it's *common*, and
*EXPECTED*.

Example:

static inline u32 __hash_32_generic(u32 val)
{
return val * GOLDEN_RATIO_32;
}

and dammit, I absolutely DO NOT THINK we should annotate this as some
kind of "special multiply".

I have no idea how many of these exist. But I am 100% convinced that
making humans annotate this and making the source code worse is
absolutely the wrong approach.

Basically, unsigned arithmetic is well-defined as wrapping around, and
it is so for a good reason.

So I'm going to have a HARD REQUIREMENT that any compiler complaints
need to be really really sane. They need to detect when people do
things like this on purpose, and they need to SHUT THE ^&% UP about
the fact that wrap-around happens.

Any tool that is so stupid as to complain about wrap-around in the
above is a BROKEN TOOL THAT NEEDS TO BE IGNORED.


Really. This is non-negotiable.

This is similar to the whole

unsigned int a, b;

if (a+b < a) ..

kind of pattern: a tool that complains about wrap-around in the above
is absolutely broken sh*t and needs to be ignored.

So I think you need to limit your wrap-around complaints, and really
think about how to limit them. If you go "wrap-around is wrong" as
some kind of general; rule, I'm going to ignore you, and I'm going to
tell people to ignore you, and refuse any idiotic patches that are the
result of such idiotic rules.

Put another way the absolute first and fundamental thing you should
look at is to make sure tools don't complain about sane behavior.

Until you have done that, and taken this seriously, this discussion is

not going to ever result in anything productive.

Linus
and a little later we are back to C promotion rules.

https://lore.kernel.org/lkml/CAHk-=wgf5mpRT_Aiw9aebX_z0i49aUbUBEPr6jk_dUaCTuR6cw@mail.gmail.com/


Classic rant stream.
 
Last edited:

WBahn

Joined Mar 31, 2012
32,925
Part of the problem is that too many people only see room for a one-size-fits-all solution -- or a one-size-fits-all description of the problem.

What is necessary/reasonable/rational in a resource-starved microcontroller running at a few tens of kilohertz with a few kilobytes bytes of ram is very different than in a machine running at several gigihertz with several gigabytes of ram. Similarly, what is reasonable for system-level code is different than what is reasonable for application code. What is sane, common, and perhaps even all-but necessary in one may well be pretty indefensible in another. Any solutions that don't recognize this reality are so at odds with reality as to be completely useless from the beginning.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
Part of the problem is that too many people only see room for a one-size-fits-all solution -- or a one-size-fits-all description of the problem.

What is necessary/reasonable/rational in a resource-starved microcontroller running at a few tens of kilohertz with a few kilobytes bytes of ram is very different than in a machine running at several gigihertz with several gigabytes of ram. Similarly, what is reasonable for system-level code is different than what is reasonable for application code. What is sane, common, and perhaps even all-but necessary in one may well be pretty indefensible in another. Any solutions that don't recognize this reality are so at odds with reality as to be completely useless from the beginning.
That's what I keep telling @nsaspook.

But he keeps using Linux as an example of C's superiority.
 

nsaspook

Joined Aug 27, 2009
16,340
That's what I keep telling @nsaspook.

But he keeps using Linux as an example of C's superiority.
Yes I do because of the correct mixture of C and ASM in exactly the right proportions far a large variety of hardware platforms and software requirements from the lower level embedded (kernel and driver) programming to user API interfaces of driver abstractions.

If you've actually written C code that's included in the Linux kernel, (like I have) it's easy to see and say C is the superior solution.
 
Last edited:

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
OK, now I'm really pissed.

"Just mix inline assembly for the important parts," @nsaspook said.

Remember this?

C:
void WS_paint(void)
{
    uint8_t lednum;

    static uint8_t bitcnt;
    static uint8_t red;
    static uint8_t green;
    static uint8_t blue;


    if (!LEDPOWER)
        return;

    for (lednum=0; lednum < NUM_TRICOLOR_LEDS; lednum++)
    {
        red    = ws_ledbar[lednum].color.red;
        green  = ws_ledbar[lednum].color.green;
        blue   = ws_ledbar[lednum].color.blue;

        bitcnt = 24;
      
        asm("BANKSEL    WS_paint@red");
        asm("dllp1:");
        asm("bcf" ___mkstr(BANKMASK(INTCON0)) "," ___mkstr(_INTCON0_GIE_POSITION) ",0");    //  **Only need to disable ints for high of pulse
        asm("bsf" ___mkstr(BANKMASK(LATD)) ",5,0");                                         //start high  --   0.0ns   (1) / 625.0ns
        asm("rlcf       WS_paint@blue,1,1");                                                //shift blue  --  62.5ns   (1)
        asm("rlcf       WS_paint@red,1,1");                                                 //shift red   -- 125.0ns   (1)
        asm("rlcf       WS_paint@green,1,1");                                               //shift green -- 187.5ns   (1)
        asm("bc         llbith");                                                           //high long   -- 250.0ns   (1)
        asm("llbitl:");
        asm("bcf" ___mkstr(BANKMASK(LATD)) ",5,0");                                         //start low   -- 312.5ns   (1) / 625.0ns / 0.0
        asm("bra        llwait0");                                                          //            --  62.5ns   (0)
        asm("llbith:");
        asm("bra        $+2");                                                              //            -- 375.0ns   (1)
        asm("bra        llbitl");                                                           //            -- 500.0ns   (1)
        asm("llwait0:");
        asm("bsf" ___mkstr(BANKMASK(INTCON0)) "," ___mkstr(_INTCON0_GIE_POSITION) ",0");    //  **can allow ints immediately after low
        asm("btfss" ___mkstr(BANKMASK(STATUS)) "," ___mkstr(_STATUS_C_POSITION) ",0");      //            -- 187.5ns   (0)
        asm("bcf        WS_paint@blue,1,1");                                                //            -- 250.0ns   (0)
        asm("btfsc" ___mkstr(BANKMASK(STATUS)) "," ___mkstr(_STATUS_C_POSITION) ",0");      //            -- 312.5ns   (0)
        asm("bsf        WS_paint@blue,1,1");                                                //            -- 375.0ns   (0)
        asm("decfsz     WS_paint@bitcnt,1,1");                                              //              -- 437.5ns   (0)
        asm("bra        dllp1");                                                            //            -- 500.0ns   (0)
    }
}
For months, this code has worked perfectly fine, and my overall project has grown since to over 40 source files and multiple thousands of lines of code.

Starting today, XC8 started bank-splitting the registers above (bitcnt, red, green, and blue) randomly, so that every time I build I get an error like:

keypad.c:101:: error: (1356) fixup overflow referencing psect bssBANK1 (0x178) into 1 byte at 0x12F7A/0x1 -> 0x12F7A (dist/default/debug/hap.debug.o 1178/0x54)
keypad.c:101:: error: (1356) fixup overflow referencing psect bssBANK1 (0x178) into 1 byte at 0x12F8E/0x1 -> 0x12F8E (dist/default/debug/hap.debug.o 1178/0x68)
keypad.c:101:: error: (1356) fixup overflow referencing psect bssBANK1 (0x178) into 1 byte at 0x12F92/0x1 -> 0x12F92 (dist/default/debug/hap.debug.o 1178/0x6C)

The error happens when I instantiate a completely unrelated new variable in a completely unrelated module, and (to top it all off), has absolutely nothing(!) to do with keypad.c.

I've confirmed the bank-splitting by examining the assembly output, so I know exactly the why of the problem. But I have no idea how the tell xc8 to keep these four variable in the same bank. And the internet is no help.

Any ideas, @nsaspook?
 
Last edited:

WBahn

Joined Mar 31, 2012
32,925
At any point in this process, have you contacted Microchip and spoken to someone there about the issues you are having? It's been well over a decade since I've had any interaction with them, so I don't know how much things have changed, but I found (back then) that it wasn't too hard to get in touch with people that really knew their products and tools, including how to exercise a finer degree of control than what was obvious from the documentation.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
At any point in this process, have you contacted Microchip and spoken to someone there about the issues you are having? It's been well over a decade since I've had any interaction with them, so I don't know how much things have changed, but I found (back then) that it wasn't too hard to get in touch with people that really knew their products and tools, including how to exercise a finer degree of control than what was obvious from the documentation.
As a matter of course, I tend to try to discover the problems and solutions on my own -- it's the way I learn.

This is today's problem -- only a few hours into it so far, and most of that time has been consumed locating the cause of the error (which isn't all that apparent based on the error text itself).

I like to knee jerk here. Spook will tell me what to do. If not, I've already got ideas of my own of things to try.
 

Thread Starter

joeyd999

Joined Jun 6, 2011
6,334
Also, @WBahn, please try to keep in mind that this thread is not intended to solve my problems, but to document a frustrating journey I've been force to embark upon against my wishes.
 
Top