Assembler vs C

Go To Last Post
33 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is not intended to be one of those time wasting arguments about which is best.
Before I started with AVR's I used to develop using 8051FA MCU's. At the time most of the work I did used just the MCU without external ram or program memory. I did commercial projects such an 8 channel keypad house alarm with LCD and telephone dial up. It had many features.
The point that I am making is that was all done in 8k of program memory and 256 bytes of ram.
After having programmed in assembler for a couple of years I switched to C. I used Keil's C51.
At first I was sceptical but was convinced after having compared the resulting assembler that C51
produced. After that I never found use for assembler - in fact the C most of the time produced better assembler code that I could ever have done. Now I develop using AVR's & GCC and the one thing I have noticed is very little seems to fit into 8k and 256 bytes of ram. I am not very knowledgeable when it comes to AVR assembler so am not that sure how efficient GCC is. Or is it perhaps that because the 8051 incorporates a boolean processor which includes bit mapped memory that programs are more efficient?
I would like to here some views regarding this.. thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A good starting point would be if you presented a small app, but still complete, and point to where or in what way you think it consumes too much RAM or flash or CPU clocks or...

Here are three questions that you should answer:

Do you see what you think is high resource consumption for a very small application? (If so, please understand that there is an initial foxed memory and run time cost for any AVR-GCC app, i.e. the startup code running etc.)

I assume you have checked that the compiler is running with optimization activated?

Are you doing floating-point calculations?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One real silly question - but you do have optimisation switched on don't you?

On the whole avr-gcc produces pretty "tight" AVR asm code and it seems to be getting better - the 4.7.2 in AS6.1 is really good at code generation.

I'd be interested to know what it is you are trying to do in 8K.

If, like Johan, guessed, you are using FP then do make sure you are linking with libm.a

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
AVR-GCC app, i.e. the startup code running etc

This is common to most compilers.
I very seldom use floating-point unless their is a need which cannot be done with interger.

Optimisation is on.
It is not something that I am currently trying to do in 8k. This is just an observation after using AVR's over a number of years.
I just feel that when I do projects similar to those that I did using the 8051 I tend to need a lot more flash and ram.
I was hoping that there is somebody that uses both currently who could perhaps write a simple program and compare the outputs.
If not , I guess when I have a little more spare time I could try re-learn the c51 ide and do it :)

Last Edited: Thu. Sep 12, 2013 - 03:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First, I know of no 8k AVR that has only 256 bytes of ram, so I don't really see the point of comparing it with a micro that does. Second, surely it matters what the code is doing that determines how much ram you are using, not the compiler. There are certainly things you can do that can eat up ram, and practices that can keep the ram usage down.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'Freak "danni" will opine that x51 is tighter than AVR8. I don't have a lot of direct experience, but I've packed quite a bit into Mega48/88 production apps over the years.

Indeed, even the 512 bytes of SRAM can occasionally seem tight on a Mega48. But that is explained by the app, such as a full 256-byte Modbus RTU buffer.

Quote:

Or is it perhaps that because the 8051 incorporates a boolean processor which includes bit mapped memory that programs are more efficient?

I'm rusty on the x51, but IIRC some of the "bit mapped memory" is the I/O bits--and the AVR's have that. In addition, with 32 GP registers (and GPIOR) one can have the equivalent of bit-mapped memory ala CodeVision's "bit" type.

If I had to make a generalization, AVR8 and x51 should be "about the same" in program size. I cannot think of why SRAM usage for the same app and the same program structure approach would be much different in one versus the other.

The mainstream AVR8 C compilers should produce at least "decent" code size, often "very good" to "excellent".

As mentioned, perhaps your builds are not using the best set of options?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, there are some applications that will use less flash memory on an AVR. Most will be marginally larger. Say 9kB vs 8kB. If you start using larger memory models, the 8051 bloats rapidly.

The RAM usage is the real pain with 8051. The comparable AVR has 16kB flash and 1kB of SRAM.

THe Keil Compiler is pretty good. It employs lots of tricks to overlay function parameter storage etc. It will put anonymous strings into CODE memory automatically.

Once you know the tricks with AVR-GCC, you will find it competes very well with C51.

Most apps will execute far faster on a 16MHz AVR than a 24MHz 8051. They are faster than a modern AT89LPxxx 1-cycle chip too. Only the SiLabs 8051 1-cycle chips give the AVR a run for the money. But they are clocked at 100MHz. You might just as well use an ARM-Cortex chip.

Most non-GCC AVR compilers are intelligent with anonymous strings, and flash handling in general.

It all really comes down to your kind of app. 8051 bit-twiddling is pretty code-efficient. Keil f-p maths is pretty code-efficient. AVR-GCC libm.a is better than 'other' toolchains.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
THe Keil Compiler is pretty good. It employs lots of tricks to overlay function parameter storage etc. It will put anonymous strings into CODE memory automatically.
That might explain the SRAM usage.
avr-gcc will not put anonymous strings into flash unless told to do so.
Until recently, it not have a pointer type that would allow pointing to either SRAM or flash.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

FWIW, the TI/Maxim benchmark study came up with 5100 bytes for Mega8 and 6800 for x51 using IAR compiler.
http://www.maximintegrated.com/p...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 8051 is small (compared to AVR) when:
use of the first 128 byte of RAM.
when the "calculation" can stay inside 8 registers.
the ISR can use the bank switching
use of 8 bit pointers and tables.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The 8051 is small (compared to AVR) when:
use of the first 128 byte of RAM.
when the "calculation" can stay inside 8 registers.
the ISR can use the bank switching
use of 8 bit pointers and tables.


I'll believe you, I guess. I'm going from memory; the last x51 I did was a decade ago but I did a fair amount in the '80s.

I'm trying to think about where the one-byte op codes would help. Basically that would be register/register(/accumulator) operations, or indirect. Direct and immediate are two bytes.

Or, perhaps, accumulator operations from direct? Then you'd have ADD A,var in two bytes instead of the AVR's LDS/ADD two words. You still need two more bytes for MOV var,A for the result. Hmmm--4 bytes vs. 6 might well add up?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The 8051 is small (compared to AVR) when:
use of the first 128 byte of RAM.
when the "calculation" can stay inside 8 registers.
the ISR can use the bank switching
use of 8 bit pointers and tables.

Perhaps it is that type of small app that the OP is working with? Still, a full Mega88 is a pretty good sized app IME. Say, a comms link and a character LCD display and some menus and some buttons and some input signals/ADs and some calculated output signals. I'm rarely surprised with the code size on my small AVR apps. The exception seems to be when 32-bit operations (including divide) are needed. Lots of register-whomping setting up and storing from the operations, plus the code size of the primitives themselves.

Atmel did some benchmarking (to promote the AVR, of course). AVR came out smaller in the supposed "real apps" as well as in the small-function fragment.
http://mathcs.slu.edu/~fritts/CS...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do not believe same code compiled for '51, AVR8, PIC8 or other 8-bitter can occupy more or less ram on different architectures.
AFAIK ram is only used for globals, stack and heap. The globals and heap do not depend on the architecture (assuming structs are packed and data is aligned). And in stack there can be minor pushpop differences (ignoring the fact that stack depth estimation is not a trivial task) that should not exceed the algebraic difference in count of general purpose registers (32-2=30 in case of AVR and '51).

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

And in stack there can be minor pushpop differences (ignoring the fact that stack depth estimation is not a trivial task) that should not exceed the algebraic difference in count of general purpose registers (

Well, besides the "stack frame" different architectures might have different stuff on the stack for CALL/RET. Small AVR8 would just have the 16-bit return address. I'd guess x51 the same. (But it isn't unheard of for an architecture [or compiler implementation] to carry a bit more stuff around.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the problem with the AVR for code size is that it can't do anything to memory, where the 8051 can do a lot, (but only to low 128 byte RAM and I/O)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

the problem with the AVR for code size is that it can't do anything to memory, where the 8051 can do a lot, (but only to low 128 byte RAM and I/O)


That's what I tried to go through above. Now, perhaps the compiler overall will be more clever than a straightforward "add 5 to SRAM 8-bit variable". On AVR, that would be a two-word LDS, one-word SUBI, two-word STS. 10 bytes.

A naive x51 might be MOV (2), ADD immediate (2), and MOV (2). 6 bytes? I guess it could add up. (Of course there would be alternate sequences on the x51 depending on A contents and how you get the "5".)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 8051 has 32 bytes of bit addressable ram. These are true bit variables each with an address. It did require a slightly 'modified' version of C to use it. But if you need to know simple on/off status of many things it can save a lot of space because there are instructions that can manipulate them the same as GCC manipulates bytes. That is what the boolean processor does. It also has a swap instruction which swaps the lower nibble with the upper. Also the paged 8 byte registers allow for simple implementation of a mini rtos.
I do prefer the AVR because it is simpler to use. Currently I use the Xmega and think its a fantastic chip. Although if Atmel added something like the bit registers and the instructions to go with it and perhaps a more flexible memory model that allows easier moving data between ram, flash and eeprom it would be unbeatable. Those are the 2 things that I have always missed since moving from 8051 to AVR

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

The 8051 has 32 bytes of bit addressable ram. These are true bit variables each with an address.

While not exactly the same, the AVR access to high GP registers with SBRr/CBR, all GP registers with SBRC/SBRS, and other functions such as BLD/BST, coupled with low I/O primitives SBI/CBI/SBIC/SBIC give much of the same facilities IMO. If indeed you are well-versed in both architectures you could find an advantage in one or the other. IME while a few bits (up to several bytes) can be an important part of an app I don't see how e.g. 8 bytes vs. 16 bytes would be that important to code size. Perhaps.

Quote:

It also has a swap instruction which swaps the lower nibble with the upper.

??? And "SWAP (A)" is any different than the AVR SWAP on any of the 32 GP registers?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
??? And "SWAP (A)" is any different than the AVR SWAP on any of the 32 GP registers?
oops did not realise it had one :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I quite often compile programs for both AVR and 8051.

I have several AVR C compilers but only SDCC for the 8051. Whereas SDCC is 'competent', Keil's C51 is vastly superior. Mind you, I am not prepared to pay $1000s for an 8051 compiler.

You just have to be realistic. Use the most suitable MCU for your application. Depending on volume, manufacturing cost and development cost will have different significance.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
The 8051 has 32 bytes of bit addressable ram.

That is easy to implement. 32 bytes times 8 bits is an 8-bit addressable binary variables in its own separate data space. So it is enough to allocate 32 bytes of data and include snippets for set/clr/toggle/get(bit* arg) (~40 bytes total) and that would the difference in code size.
And as mentioned, if you do not necessarily need 256 bit variables in the application, there are bit addressable GPIORs and spare IOs, with atomic set, clear, toggle and conditional sbis+sbic in one op-code.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Brutte wrote:
Quote:
The 8051 has 32 bytes of bit addressable ram.

That is easy to implement. 32 bytes times 8 bits is an 8-bit addressable binary variables in its own separate data space. So it is enough to allocate 32 bytes of data and include snippets for set/clr/toggle/get(bit* arg) (~40 bytes total) and that would the difference in code size.
So far as I can tell, the bit variables in the 8051 are not indexable.
To simulate them, 'tis enough to have 256 bit fields and ensure atomic access.

"SCSI is NOT magic. There are *fundamental technical
reasons* why it is necessary to sacrifice a young
goat to your SCSI chain now and then." -- John Woods

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Keil's C51 is vastly superior. Mind you, I am not prepared to pay $1000s for an 8051 compiler.

Coming back to where I started, perhaps it is all about how good is GCC when compared to the comercial compilers?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Coming back to where I started, perhaps it is all about how good is GCC when compared to the comercial compilers

It is better (efficiency of code generated) than Imagecraft and Mikro C, it's about equal to CodeVision, it is just a little worse then IAR. If you have $3,000 available it may therefore be worth getting a copy of IAR.

Having said that 100 bytes in the difference over 8K of code only actually becomes important when it is 100 bytes OVER the 8K ;-)

But if you are building a million seller and a $3,000 copy of IAR means you can use the 8K device when otherwise you'd have to pay $0.3 per unit extra to use the 16K one. Then, yes, the compiler pays for itself many times over.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
It is better [than] than [beep] and [beep], it's about equal to [beep], it is just a little worse then [beep].

Now you will just have to wait for Bob, Lee and perhaps someone else, and then the war begins.

For the rest of us: Don helmets! To the shelter!

:D

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Fri. Sep 13, 2013 - 09:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No. Everyone makes their own decisions.

There is no "GCC" for the 8051.
SDCC is a "free" compiler but it is not GCC.

I will quite happily state that Keil C51 is vastly superior to SDCC.
I will quite happily state that Keil RealView is vastly superior to ARM-GCC.

I would never consider buying a C51 licence.
If I had a lucrative commercial project, I would consider buying a RV licence.

It is very unlikely that I would consider buying an IAR licence for 8051, AVR or ARM.

The GCC family of cross-compilers is perfectly adequate for AVR or ARM. Your Mileage May Vary.

Incidentally, a C program that demonstates a Graphics TFT library is 26000 bytes with SDCC and 17130 bytes with CodeVision. It runs a lot faster too. I suspect that Keil would be significantly better than SDCC.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But if you are building a million seller

If that is 100 bytes above 8k, then it would be cheaper and faster to tweak a part of the GCC code asm/ld and squeeze that to free 100 bytes of flash. For example tweaking crt to load .data not from flash but from .eeprom is very easy and saves sizeof(.data) of flash. I suppose sizeof(.data) is 400 bytes minimum in a typical 8kiB application.

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow that's a nice idea!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Coming back to where I started, perhaps it is all about how good is GCC when compared to the comercial compilers?


And again going back to where we started, and again trying not to start a "flame war", I've seen enough posts and discussions over the years here to come to the conclusion that GCC for AVR will generate "respectable" to "very good" to "excellent" results. Now, I've also seen many threads about doing it "right" in the hands of experienced users. The biggest example(s) seem to be using the correct lib___ and "bloat" with -O0.

Quote:
Now I develop using AVR's & GCC and the one thing I have noticed is very little seems to fit into 8k and 256 bytes of ram.

So this is where it gets puzzling, at least to me. Without getting into the last +/- 10% and whether one compiler on a certain benchmark is a few percent better/worse than another, IME I can pack a lot of app into an 8k AVR. As discussed earlier, I can't see where SRAM usage should matter much for any given app on X51 vs. AVR.

Perhaps give an example program that can be dissected a bit. The .MAP and build options should tell a lot. For SRAM, are constant strings in flash?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
is 26000 bytes with SDCC and 17130 bytes with CodeVision

SDCC is a simplified/basic C compiler maintained by a bunch of enthusiasts. It does not even implement many ANSI C features or anything you could call "optimization" and it is targeted for hobbyists that do not really care if the code is small (because bigger chip costs $0.2 more) or fast (because you can overclock the chip by 20% for DIY project). Its main aim is to be free and give basic support for a variety of small chips (among them '51 and PIC8 included, AVR8 support was dropped recently).

No RSTDISBL, no fun!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely GCC is also maintained by a bunch of enthusiasts too.

I make no apologies for using SDCC for the 8051. After all, C51 'evaluation version' will only compile user C to 2kB of object code. I would pay $100-$200 for toolchain but not $3000.

Yes, I accept that if I want to use uVision, I have to pay what they ask.

The AVR situation is quite different. GCC, CodeVision, Rowley all produce acceptable code for a reasonable cost. I am a hobbyist.

Likewise with ARM. GCC tools produce acceptable code.

So everything comes down to your particular situation. As suggested earlier, if you can save $0.50 on a million-seller, you pay for the best tools and employees.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Surely GCC is also maintained by a bunch of enthusiasts too.

The front-end (and the mainstream backends, but that's irrelevant here), much of binutils, and, also importantly, much of the infrastructure, are maintaned by paid professionals and backed by huge corporations.

There are also Atmel employees contributing to avr-gcc and kin. I'd like to see them doing it properly through the designated "community" means rather than playing on their private playground, but still they do.

OTOH, while several mcu manufacturers incorporated SDCC into their toolchains in the few last years (e.g. Infineon and also Atmel), I know of NO contribution from them into the mainstream SDCC - they don't even care to contribute device-specific headers...

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will add this.
Over the time I have used different compilers.
In general I'm not impressed with what the IAR generated code, but there is rarely any problems with your code if you change type of MPU.
I have never used keil for the 8051 (only for some tests), and the one I used at the time BSO-tasking did as good or better job. (at the time we had to use that because it was the only one that could run on unix).
For the AVR I normally use GCC (if not ASM), and when you look at the optimized code it's easy to see that the C compiler part is very very good (to see big sections that isn't needed etc.), but the problem is the backend is not 100% optimal.
I have tested the CV compiler and if it's simple and direct code it's very good, but it hunts it back with more complex code where the GCC is better (a good example is try to make the classic swap function in CV and you will find some ugly code).
I have tested the image craft compiler and in the beginning I liked it because I have used the same compiler (it's based on the LCC compiler), and it make solid code but I don't think it's optimal (I have to add that I have only used the free version and the pro. ver. have some extra optimizations, and it's a while back. )
And I will still say that ASM is the way to go if you want to save the 0.50$ for millions. there is a mush bigger difference between the best C compiler and ASM than the best and worst (real :) ) C compiler.
And for projects with 8K or less code it's easy to deal with, but you need to know how to structure the hole project.