This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

35% smaller, and 14% faster code!

There is a new 8051 C compiler in beta test that beats Keil's compiler by 35% code size, and 14% speed, on the Dhrystone benchmark. And, there is no need to select a memory model or use special keywords to control data placement.

More details here: www.htsoft.com/.../silabs8051beta

Parents
  • Even if the embedded engineer doesn't do such formal qualification testing methods, the "debugging" process is basically the same as the FQT. You break at a known point (in "C") and track/trace the flow and data through the unit under test (the function or suspected area of error), and figure out why your logic/implementation is wrong.

    Typically this is done at the assembly level and not simply at the "C" level since the 'competent' can easily see the "C" level errors quickly. It is our 'advanced' errors in thought that we spend all of our time "debugging" the assembly.

    I'm not sure I have understood this. You appear to be saying that given an error in a 'C' program that is caused by:

    a) Faulty logic
    or
    b) Faulty implementation of correct logic

    you might find yourself debugging at assembly level to spot the error?

Reply
  • Even if the embedded engineer doesn't do such formal qualification testing methods, the "debugging" process is basically the same as the FQT. You break at a known point (in "C") and track/trace the flow and data through the unit under test (the function or suspected area of error), and figure out why your logic/implementation is wrong.

    Typically this is done at the assembly level and not simply at the "C" level since the 'competent' can easily see the "C" level errors quickly. It is our 'advanced' errors in thought that we spend all of our time "debugging" the assembly.

    I'm not sure I have understood this. You appear to be saying that given an error in a 'C' program that is caused by:

    a) Faulty logic
    or
    b) Faulty implementation of correct logic

    you might find yourself debugging at assembly level to spot the error?

Children
  • If you use #define expressions you may get into troubles with multiple increments/decrements that isn't visible when you single-step the C source. You either have to run the pre-processor to get the code expansion, or single-step the assembler code.

    C++ also have a bit of magic that can require assembler debugging unless you already "know" where you should put a breakpoint to catch the next step.

  • Yes. that is what I am saying. Most errors are either faulty logic or the faulty implementation of correct logic... and of course the faulty implementation of fautly logic.

    At the "C" level, these can be found 'easily' since your emulator/simulator can show you the logical flow as you single-step through the high-level "C" code, and you watch the data-stores change accordingly. But since the 'hard' problems take a much larger percent of our debugging time, we usually are single-stepping through the underlying assembly code that supports each of the "C" statements in order to find our mistakes. Per Westermark just made a clear and common 'error' that usually is found at the assembly level.

    The reason I elaborate on this distinction has to do with the highly-optimized code that causes the underlying assembly language to be seemingly scattered and dis-jointed due to the use of shared code segments and other "odd looking" (but valid) code that the compiler may generate.

    --Cpt. Vince Foster
    2nd Cannon Place
    Fort Marcy Park, VA

  • Per Westermark just made a clear and common 'error' that usually is found at the assembly level.

    I'm not sure that I see that as an example of something that might need to be debugged at assembly level. It's a straightforward 'C' level error caused by a failure to understand either side-effects, macro expansion rules or both. As such I wouldn't expect a competent 'C' programmer to make the error, never mind be unable to spot it at the 'C' level.

    I would be interested to see a concrete example of an error that a competent 'C' programmer might make that would not be more easily spotted by reviewing the 'C' code rather than stepping through compiler generated assembly code.

  • I have to agree with Jack, although I think that making mistakes has little to do with what he considers "competence". When I have trouble with macros I usually look at the preprocessor output, I don't bother to debug them in assembly.

  • I would be interested to see a concrete example of an error that a competent 'C' programmer might make that would not be more easily spotted by reviewing the 'C' code rather than stepping through compiler generated assembly code.

    Here's one. Taken from real life, slightly simplified.

    unsigned int i;
    unsigned int some_array[12];
    
    ...
    
    for(i = 8; i < 12; i++)
    {
       some_array[i] = 0xFF;
    }
    

    After the loop, some_array[9...11] were found to be unmodified. No other tasks or ISRs are access some_array at the same time. Did you find the error in the C code ?

  • I got a bit of code written by another developer, and containing a library.

    What wasn't obvious whas that the nice guy had decided to create a function-looking #define without the very common curtesy to select all capitals.

    Would you suspect the following code to step the pointer twice?

    while (*msg) put_data(*msg++);
    

    By your implication, I was incompetent for assuming that the documented "function" actually was a function. Sumething documented as a function should really behave as a function, don't you think?

    Since I assumed it to be a function (as the documentation claimed), I saw no need to look at any preprocessor output. However, single-stepping through the code with mixxed assembler/C made it obvious that the function call did not do what I expected, and why the extra increment managed to step past the termination character. If msg had had multiple characters, I might have noticed that only characters at even positions was emitted, but in this case my only character was emitted (as expected), but then followed by a very large number of random junk.

    Life is a lot easier when you have written every single line of the code - as soon as someone else have been involved, you have to assume that they have followed the traditional best-practices or you will never manage to get a final product.

  • If what you are saying is true, then the compiler that translated that fragment of code is broken. Use a different compiler - one that you can trust.

  • Did you find the error in the C code ?

    Given that snippet in isolation I can see no error. Please enlighten me.

  • Given that snippet in isolation I can see no error. Please enlighten me.

    There isn't one (the snippet was all that was necessary to reproduce the error, without any ISRs or multitasking). The programmer made one of two possible errors: Either blindly trusting the compiler to generate correct assembly code, or not religiously sifting through the compilers errata sheets to check for this situation.

    Looking at the assembly code, however, it became quite clear that the compiler generated a completely bogus target address for the looping command used in the for-loop, which caused the microcontroller to jump out of the loop after the first iteration.

    Not calling any names here, but that was the compiler supplied by the manufacturer of the chip, with no alternative compilers available. When presented with the C code and the corresponding assembly, their tech support commented "We do not think this is a compiler bug.". I've not contacted them again after this. Most of the program was written in assembly, anyway, which was probably a good thing.

  • If what you are saying is true, then the compiler that translated that fragment of code is broken.

    Why do you think that?

  • Not calling any names here, but that was the compiler supplied by the manufacturer of the chip, [...]

    I don't know why I so suddenly start to think about Microchip...

  • The programmer made one of two possible errors: Either blindly trusting the compiler to generate correct assembly code, or not religiously sifting through the compilers errata sheets to check for this situation.

    You've missed the point. I was after an example of the sort of error being discussed - a 'C' coding mistake caused by faulty logic or faulty implementation of correct logic. It's a given that one would have to inspect the assembly output if there is in fact no error in the 'C' code.

  • I don't know why I so suddenly start to think about Microchip...

    Never worked with any of their products, sorry. But I think there are alternative compilers available for their architectures.

    In my case, there was no alternative. And I guess the response from tech support would have been much, much different if I hard worked on a large-volume project (millions of units per year, like ... cellphones) instead of one with a paltry 10k to 100k units per year.

    Oh, and nastily enough, the compiler generated completely correct assembly if the debug symbols were turned on (yes, with everything else, including the optimization settings, being unchanged). Took me a while to figure out why I couldn't "reproduce" the error with my debug version, while it was perfectly reproducable with the release version.

  • Why do you think that?
    Well, apart from anything else, I pasted the code fragment into a C file and compiled it with a few of the variety of compilers I have on hand. All produced code that delivered the expected result. That's empirical confirmation of my assessment by inspection of the code that the description of the observed behaviour was at odds with the behaviour described by the C code itself.

  • I was after an example of the sort of error being discussed - a 'C' coding mistake caused by faulty logic or faulty implementation of correct logic.

    Well, any case of lawyer code (e.g. use of code with effects not specified by the C language standard) would suffice there. Even the most competent C programmer cannot tell whether the code will do what it is supposed to do without either knowing the implementation details of the compiler or looking at the generated assembly.

    (And no, I don't consider knowing by heart what

    some_function(++a, ++a);
    

    does on seven different compilers to be part of being a competent C programmer. A competent C programmer will know that this is heavily compiler dependent and avoid such expressions whenever possible. There is no way of knowing whether this will work as intended by just looking at the C code)