Assembled AVR program size vs size in flash

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

I’m trying to understand the difference between the hex file that avrasm2 creates and I write to flash using avrdude and the same flash that I read back again using avrdude.

 

I'm using a homebrew board with an ATMEGA328P and a USBtiny programmer. I’m experimenting with very simple and short programs.

 

Assembling the program:

avrasm2 -fI blink.asm

 

The size of the hex file is 181 bytes.

 

Writing the program to the ATMEGA328P”

avrdude -p m328p -c USBtiny -b 57600 -U flash:w:blink.hex

 

The program works ok.

 

Then reading the program back from the ATMEGA328P:

avrdude -p m328p -c USBtiny -b 57600 -U flash:r:"blink2.hex":i

 

The size of this hex file is 288 bytes. It’s difficult to match this hex file to the original. I see some parts that are the same but obviously it includes more of something. Variables are not stored in flash, so that shouldn’t account for the extra bytes.

 

I can rewrite either of these 2 hex files back to the ATMEGA328P, and they both work ok, even though blink2.hex is 107 bytes longer. Some other programs are 300-400 bytes longer.

 

Does this have something to do with how avrdude works? Or maybe flash page sizes in AVR chips?

 

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

Wikipedia has a nice explanation of the intel hex file format. The size of the hex file has some relation to the actual binary size but you can have records that do nothing to the binary but will alter the hex file size.
Once you understand the details of the hex file, you will be able to load the hex file into an editor and observe the differences.

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

Kartman wrote:
Wikipedia has a nice explanation of the intel hex file format. The size of the hex file has some relation to the actual binary size but you can have records that do nothing to the binary but will alter the hex file size. Once you understand the details of the hex file, you will be able to load the hex file into an editor and observe the differences.

Thanks - that does help. I hadn't gotten far enough into the Intel hex file format to realize it added that much overhead to the file size. But there is also something else adding to the program size after it is in flash. It seems to have something to do with labels. If I flash a minimum program, for example just a single RJMP, I don't get the extra size. But if I have some labels, I do. I know variables are saved in EEPROM, so I'm not sure why using labels affects flash size. As you can see, I've only recently gotten into assembly programming. 

 

 

 

 

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

moallen wrote:
I know variables are saved in EEPROM,

 

Not entirely true - your code determines if anything is stored into eeprom - there's no automagic.

 

I'm not sure what you're observing. The listing file shows you what code is generated and at what addresses. The hex file is merely a container to transfer the binary object.

 

Post your source, listing and hex files. We should be able to sort out what is happening.

 

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

Here's my commands to assemble, flash, and read the flash back, plus the listings. This particular program (blink.asm) comes up with a bunch of F's in flash that are not in the assembled hex file. This might be a different issue that what I saw in other programs where flash was larger than the original hex.

 

avrasm2 -fI blink.asm

 

avrdude -p m328p -c USBtiny -b 57600 -U flash:w:blink.hex

 

avrdude -p m328p -c USBtiny -b 57600 -U flash:r:"blink2.hex":i

 

Thanks for taking the time to get me squared away on this!

 

Attachment(s): 

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

te assembler generated hex file only outputs the bytes it needs to change. You can see in blink.hex the records for each of the vectors, then the code itself. In blink2.hex, the data has been padded with 0xff's to give 32 byte records. In reality there is no difference - the erased flash is 0xff anyways. The bytes of interest are the same. 

 

put it another way - the assembler knows which bytes it needs to change whereas avrdude just reads an array of bytes from the flash. 

 

You didn't supply a listing file - the 'listing' you supplied was the build output. Read up on the avrasm2 docs on how to generate the file. I haven't done avr asm for many years, so I can't remember the required incantations.

 

the inc file has names for the vector addresses - use these rather than .org 0x0020 so less chance of mistakes.

 

In your overflow handler you need to save/restore the status register. Your isr code changes the flags so this will upset the main line code.

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


 

As you mention avrasm2 I'm assuming you are on Windows and making the further gross assumption that you might actually be using AS7? If that is the case then AS7 also comes with a whole bunch of other tools besides avrasm2. If you use Tool-Command Prompt this starts a command prompt where those tools are available to you. One tool that is really there as part of the C/C++ compilers but that has more general use is avr-size. So if I take your two files in #5 and do:

 

So one of the files has 50 bytes and the other has 112

 

As you have therefore seen you can't really tell how much binary is represented by the size of the .hex file though sometimes if you divide by about 2.5 to 3.5 you may get the size (kind of). So for blink_1.hex there are 50 bytes of code and the file is 182 bytes. 182/50 is 3.64 in fact so that particular file has a lot of "overhead". In the other case there's 112 bytes of binary in a file that is 289 bytes so the ratio there is 289/112 which is 2.5

 

So to get an idea maybe just divide by 3 and you might be in the ball-park?

 

If you want to know the real numbers then either use avr-size or look at the assembler listing or simply trust what avrdude tells you:

C:\avr>avrdude -p m328p -c USBtiny -b 57600 -U flash:w:blink.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "blink.hex"
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: writing flash (112 bytes):

BTW another tool in the "toolbox" that comes with the C compilers in AS7 and is also available for the Asm programmer to use is avr-objcopy. This can convert file formats (among many other things) so I can turn your .hex files back to binary with:

 

 

Having done that if I use an excellent tool from the internet such as "Hex Workshop":

 

 

that is:

 

http://www.hexworkshop.com/overview.html

 

it has a compare function so I can do:

 

 

and it shows:

 

 

So basically what is different between the two is that one appears to have the interrupt vector area all set to 0x00 and the other has it set to 0xFF but otherwise these look like the same code.

Last Edited: Thu. Feb 13, 2020 - 10:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 2 of you have given me plenty to wrap my head around, which will probably take a little time. I'm using Hex Editor Neo, the standard free version. I do need to either upgrade it or get Hex Workshop so I can do color comparisons.  

 

I'll be back if I hit a brick wall understanding what you've posted.

 

 

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

blink.hex contained discontiguous data.

blink2.hex did not.

Apparently avrdude stated at zero and kept writing blink2.hex

until avrdude had read the last non-FF.

 

Iluvatar is the better part of Valar.