Misc questions about generated code

Hi all

Just joined and still trying to get a feel for the forum so my apologies if I have posted in the wrong place.
I have several questions relating to the code generated by AVR for a compiled sketch.

  1. Why is there an elf file over and above the hex file?

  2. How does one disassemble the compiled hex file?

  3. Can one use inline assembler in the IDE and if so how?

  4. At the end of loop(), typically how many clock cycles are taken up to return to the beginning of the loop?

Thank you in advance.

The .elf file has source inside it, helpful for working out what it does.

eg.

Disassembly of section .text:

00000000 <__vectors>:

HardwareSerial::HardwareSerial(ring_buffer *rx_buffer, ring_buffer *tx_buffer,
  volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
  volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
  volatile uint8_t *ucsrc, volatile uint8_t *udr,
  uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udrie, uint8_t u2x)
   0:	0c 94 35 00 	jmp	0x6a	; 0x6a <__ctors_end>
    n += write(*buffer++);
  }
  return n;
}

size_t Print::print(const __FlashStringHelper *ifsh)
   4:	0c 94 5d 00 	jmp	0xba	; 0xba <__bad_interrupt>
	timer0_millis = m;
	timer0_overflow_count++;
}

unsigned long millis()
{
   8:	0c 94 5d 00 	jmp	0xba	; 0xba <__bad_interrupt>
   c:	0c 94 5d 00 	jmp	0xba	; 0xba <__bad_interrupt>

...

00000068 <__ctors_start>:
  68:	1a 02       	muls	r17, r26

0000006a <__ctors_end>:
  6a:	11 24       	eor	r1, r1
  6c:	1f be       	out	0x3f, r1	; 63
  6e:	cf ef       	ldi	r28, 0xFF	; 255
  70:	d8 e0       	ldi	r29, 0x08	; 8
  72:	de bf       	out	0x3e, r29	; 62
  74:	cd bf       	out	0x3d, r28	; 61

00000076 <__do_copy_data>:
  76:	11 e0       	ldi	r17, 0x01	; 1
  78:	a0 e0       	ldi	r26, 0x00	; 0
  7a:	b1 e0       	ldi	r27, 0x01	; 1
  7c:	ec ee       	ldi	r30, 0xEC	; 236
  7e:	f6 e0       	ldi	r31, 0x06	; 6
  80:	02 c0       	rjmp	.+4      	; 0x86 <.do_copy_data_start>

00000082 <.do_copy_data_loop>:
  82:	05 90       	lpm	r0, Z+
  84:	0d 92       	st	X+, r0

00000086 <.do_copy_data_start>:
  86:	a0 31       	cpi	r26, 0x10	; 16
  88:	b1 07       	cpc	r27, r17
  8a:	d9 f7       	brne	.-10     	; 0x82 <.do_copy_data_loop>

0000008c <__do_clear_bss>:
  8c:	11 e0       	ldi	r17, 0x01	; 1
  8e:	a0 e1       	ldi	r26, 0x10	; 16
  90:	b1 e0       	ldi	r27, 0x01	; 1
  92:	01 c0       	rjmp	.+2      	; 0x96 <.do_clear_bss_start>

00000094 <.do_clear_bss_loop>:
  94:	1d 92       	st	X+, r1

00000096 <.do_clear_bss_start>:
  96:	af 3b       	cpi	r26, 0xBF	; 191
  98:	b1 07       	cpc	r27, r17
  9a:	e1 f7       	brne	.-8      	; 0x94 <.do_clear_bss_loop>

0000009c <__do_global_ctors>:
  9c:	10 e0       	ldi	r17, 0x00	; 0
  9e:	ca e6       	ldi	r28, 0x6A	; 106
  a0:	d0 e0       	ldi	r29, 0x00	; 0
  a2:	04 c0       	rjmp	.+8      	; 0xac <.do_global_ctors_start>

The .hex file is the raw machine code.

eg.

:100000000C9435000C945D000C945D000C945D0024
:100010000C945D000C945D000C945D000C945D00EC
:100020000C945D000C945D000C945D000C945D00DC
:100030000C945D000C945D000C945D000C945D00CC
:100040000C94C9020C945D000C9472000C94BD00D9
:100050000C945D000C945D000C945D000C945D00AC
:100060000C945D000C945D001A0211241FBECFEFAA
:10007000D8E0DEBFCDBF11E0A0E0B1E0ECEEF6E0ED
:1000800002C005900D92A031B107D9F711E0A0E1AF
:10009000B1E001C01D92AF3BB107E1F710E0CAE645
:1000A000D0E004C02297FE010E947003C836D10739
:1000B000C9F70E9470020C9474030C940000089518
:1000C0000F931F9304E911E0C80140E052EC61E096
:1000D00070E00E94ED00C8010E94A9021F910F91DB
:1000E000089508951F920F920FB60F9211242F9327

  1. How does one disassemble the compiled hex file?

If you have the .elf file it is better to work with that:

avr-objdump -S -z (filename).elf

If you only have the .hex file (eg. you downloaded it from a chip) you can do this:

avr-objdump -j .sec1 -d -m avr3 (filename).hex

  1. Can one use inline assembler in the IDE and if so how?

You don’t normally need to, however an example from Optiboot.c:

void uartDelay() {
  __asm__ __volatile__ (
    "ldi r25,%[count]\n"
    "1:dec r25\n"
    "brne 1b\n"
    "ret\n"
    ::[count] "M" (UART_B_VALUE)
  );
}

  1. At the end of loop(), typically how many clock cycles are taken up to return to the beginning of the loop?

A handful. You don’t normally need to know that. Why does it matter? You now know, anyway, how to find that out.

Hi Nick

Thank you very much for the detailed answers, much appreciated.

  1. As long as it takes for a function return, loop and function call.

I'm glad someone asked the question. I looked around for a .hex and a .elf file, and could not find either. I looked through the Directory containing the IDE executable, as well as an Arduino directory I found in one of the User directories (Windows 7 system). I did find a preferences file in the latter directory, but that's all.

Is there something I have to set up in order to have them saved?

If you enable verbose output (using File Preferences) the where will be disclosed. Grab them before they go away. The build directory is temporary.

Got the directory. Thanks!

However, I don't see any source in the .elf file. Do I assume I have to run something to extract Nick's really nice disassembly from the elf file?

lar3ry:
Got the directory. Thanks!

However, I don't see any source in the .elf file. Do I assume I have to run something to extract Nick's really nice disassembly from the elf file?

avr-objdump -S -z (filename).elf

avr-objdump -S -z (filename).elf

Thanks! That just made me realize that I must have put in Arduino 1.5.2 from a .zip file, without doing a Windows install. So I'm going to try 1.5.4 from the Windows installer and see if the ENV variables get set for the tools.

The .elf file has source inside it, helpful for working out what it does.

The .elf file doesn't actually contain any source code. It contains symbols and debugging info (like filenames and line numbers) that can be used (by programs like avr-objdump) to generate the mixed assembly/source information.

(actually, I think this is probably still somewhat broken. #line directive interferes with disassembly. · Issue #1337 · arduino/Arduino · GitHub )