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

Assembly vs C

Hi,
We have one application which was developed in c51. By applying all aptimization techniqs provided by compiler, code size is near to 20k. If we change total code to Assembly from C, how much code size can be reduced?.
Please provide me ur inputs....

Ramesh

  • If we change total code to Assembly from C, how much code size can be reduced?

    That's completely impossible to tell for any of us, because we

    * don't know what the program is supposed to do

    * haven't seen that code

    * have no idea how good your guys are at 8051 assembly

  • Hi Broeker, thanks for ur response.
    We have very good experiance in Assembly.
    I am not very comfortable with "C". That is reason I am not able to estimate.
    We want to prapose with assembly, for minimum code size.
    We want rough idea how much we can reduce?.

    thanks in advance.

  • thanks for ur response.
    you will get as good an answer form a microresistor as anywhere else. Optimized C can be more compact that assembly and it can be up to 40% more, it all depends. as an example mov p2,#44 will take the same room as p2=44; but switch{} will probably take a bit more room than jmp @a+dptr.

    So, the corect and only reply to "We want to prapose with assembly, for minimum code size.
    We want rough idea how much we can reduce" is "that depends, who knows"

    another issue is that writing "compiler friendly" C can reduce the code size dramatically.

    Erik

  • Ramesh: I presume that you are asking this question because you have a compelling need to fit an application currently available only in C source code into fixed hardware that does not have enough code space?

    Unfortunately, as Hans has pointed out, there can be no general answer to your question. However, I will try and offer some guidance.

    A program that has been really well optimised, taking full advantage of all that Keil C51 has to offer may prove difficult to beat even with carefully hand-crafted assembler. The particular reason for this is that C51 is very good at making best use of available memory (by overlaying variables) and pulling out blocks of common code into subroutines. All of which could be done by hand, but would represent a monumental task.

    On the other hand, your comment that you are "not very comfortable with C" suggests to me that you have not yet explored all the possibilities for reducing the size of the compiler generated object code. This is an area where there is simply no substitute for experience, but it is quite possible that putting effort into this area will pay dividends far quicker than embarking on a conversion to Assembler.

    Offering specific advice is very difficult, perhaps you can tell us what you have tried and what is the code size reduction that you need to achieve – then we will be more likely to be able to help.

    A good place to start is being very careful with the memory model. What RAM memory types are available to you? Careful manipulation of the memory model – selecting the ideal model on a function-by-function basis – is likely to prove the single most effective thing you can do. To do this effectively, you will need an intimate understanding of the MAP file.

  • Graham,
    good points, however
    The particular reason for this is that C51 is very good at making best use of available memory (by overlaying variables)
    overlaying variables automatically is equally possible in assembler [if main() is in C, why that is, I do not know].

    Data used in assembler stored in a segment such as

    ?DT?FormatScrippet?SZFSC SEGMENT DATA OVERLAYABLE
    is, indeed ovelaid just as local C variables.

    Erik

  • Ramesh

    My inputs (small as others have covered this much better that I can)

    memory=cheap
    man hours=expensive
    why not just get yourself a chip with more memory and move on with life? You havn't even mentioned the chip you are using.

    Andy


  • memory=cheap
    man hours=expensive


    Only when your volume is low. Our company sells product by the hundreds of thousands or millions. It would pay to have three or four engineers devoted full time for a year just to shave a dollar off the RAM cost. (Not that it would take anywhere near that much effort.)

    I agree with earlier posters that it's worth exploring ways to write C that compiles to a smaller space. On a large scale, you're not going to beat the compiler by writing assembler by hand -- at least, not by any amount that you couldn't have reached by doing similar work on the C source itself. Good assembler can be smaller than bad C, but that's an apples-to-oranges comparison.

    It helps to study the generated code from the .lst files, see what's taking up space, and then working on those parts.

    Some more specific suggestions:

    - avoid xdata access. It's very expensive to put variables in xdata; it takes a lot of instructions to load up the DPTR and move variables in and out. If you use the large memory model, beware of temporaries and long parameter lists that spill out into xdata.

    - Use data memory for the "stack", keeping your locals there.

    - write small routines. Linker optimizations will eliminate a lot of common code, but you can go ahead and make them named subroutines. Sometimes even a single line of code is worth making a routine. An 8051 takes more instructions per line of C than you might be used to with modern processors, and so smaller bits of code are good targets for reuse by making them functions.

    - experiment with caching intermediate results. Sometimes the compiler is good about this, sometimes not, and you can save space by using some intermediate variables.

    - experiment with caching dereferences. Again, sometimes the compiler is good about optimizing several references to the same structure, in source like

    myPtr->field1 = xxx;
    myPtr->field2 = yyy;
    SomeFunc (myPtr->field3);

    or the same with myStruct.myField.

    Just by changing the phrasing of the C code, we can often squeeze 10-20% on top of level 9/11 optimization out of even fairly tightly written code; more for naively written modules.

  • I agree with earlier posters that it's worth exploring ways to write C that compiles to a smaller space. On a large scale, you're not going to beat the compiler by writing assembler by hand -- at least, not by any amount that you couldn't have reached by doing similar work on the C source itself. Good assembler can be smaller than bad C, but that's an apples-to-oranges comparison.

    I disagree, it IS possible to beat the compiler by significant amounts if you know where and how. Willy-nilly changing C to assembler will gain you very little.

    OK, let us compare good C with good assembler:
    There are areas in which you can beat the compiler by significant amounts specifically in the area of handling strings.

    Let us take an example (ok, this one mainly for speed, but fresh in my mind):
    reading 1 k from one buffer and after processing the entries storing them in another buffer.

    you happen to know that the move is always in groups of 32 and you have, by using assembler, located your output buffer on a memory location where the start address is xx00h

    you can the store by what i sketch here

    move group:
    ;*** set output addr in P2val and r0
           mov  r0,r0val
           mov  p2,P2val
    gloop: movx a,@dptr
           inc dptr
    ;*** process byte in a
           movx @r0,a
           inc  r0
           djnz ....
           mov a,r0
           jnz goon
           inc p2val
    This is about 1/3 in codespace and time of the equivalent c.

    so, what is the base for the savings? combining something you know (groups of 32) with something using that knowledge (buffer address is xx00h) because your familiarity with the hardware (P2 need only opdate when r0 cross zero) and by doing so you do something based on something there are no means of "telling" the compiler.

    AGREED, Where it is possible for the compiler to do the optimum based on things you (can) tell it, the savings are very nominal.

    Taking a program at random and "deciding" to cut its codespece by 25% by switching to assembler is, in most, if not all cases, a losing proposition.

    Optimize the C (not by increasing optimizer level, but by writing good code), then find the few places where an assembler rewrite gives significant gains and do that. THEN STOP! the 80/20 rule apply here fully.

    Erik

  • ADDENDUM: I missed the last step in the post above

    Optimize the C (not by increasing optimizer level, but by writing good code), then find the few places where an assembler rewrite gives significant gains and do that. THEN STOP! the 80/20 rule apply here fully.Then apply the compiler/linker optimization.

  • I thought I'd add my 2 cents here.
    First of all, I can't see any contradiction between what Drew and Erik said. What I mean is that if you write a complex program entirely in C you'll most likely end up with smaller code than if you write it in assembly language. Of course, it is possible to make a mess in both of those scenarios, but let's assume that the programmer does a sound job.
    I think all the points raised in the discussion are good ones. To sum up, the recipe is to write good C code keeping in mind that some C language constructs translate into tighter code than others for your particular architecture. For example, in one of my projects I was writing simple menu handling code. Simply replacing 2D array indices with pointers instantly saved me more than 1K of code memory.

    Best of luck,
    - mike

  • Drew Davis said, "avoid xdata access. It's very expensive to put variables in xdata; it takes a lot of instructions to load up the DPTR and move variables in and out."

    Very true.

    See http://www.8052.com/forum/read.phtml?id=104610

    However, note once again that I say, "you may be able to significantly reduce your code size..." and, "The benefits of all this do, of course, depend upon the nature of the existing code - YMMV"

    Assembler is just another language - it is not a magic bullet!

    The mere fact that you write in Assembler rather than 'C' will not of itself make your code any smaller - it all depends on how skilled you are in using the particular language.

    As has already been mentioned, it is quite possible that an unskilled assembler programmer's code will be bigger and/or slower than a skilled 'C' programmer's code!