Вы можете использовать avr-objdump -d .elf, чтобы увидеть, что генерируется:
Давайте немного разберемся:
[jpc@jpc ~] avr-objdump -d avr.elf | sed -e 's/^/ /' | pbcopy
avr.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 09 c0 rjmp .+18 ; 0x14 <__ctors_end>
2: 0e c0 rjmp .+28 ; 0x20 <__bad_interrupt>
4: 0d c0 rjmp .+26 ; 0x20 <__bad_interrupt>
6: 0c c0 rjmp .+24 ; 0x20 <__bad_interrupt>
8: 0b c0 rjmp .+22 ; 0x20 <__bad_interrupt>
a: 0a c0 rjmp .+20 ; 0x20 <__bad_interrupt>
c: 09 c0 rjmp .+18 ; 0x20 <__bad_interrupt>
e: 08 c0 rjmp .+16 ; 0x20 <__bad_interrupt>
10: 07 c0 rjmp .+14 ; 0x20 <__bad_interrupt>
12: 06 c0 rjmp .+12 ; 0x20 <__bad_interrupt>
20-байтовая таблица векторов прерываний (по крайней мере, некоторые записи можно было бы опустить, если бы вы настаивали и обещали, что никогда не включите соответствующие прерывания).
00000014 <__ctors_end>:
14: 11 24 eor r1, r1
16: 1f be out 0x3f, r1 ; 63
18: cf e9 ldi r28, 0x9F ; 159
1a: cd bf out 0x3d, r28 ; 61
1c: 02 d0 rcall .+4 ; 0x22 <main>
1e: 05 c0 rjmp .+10 ; 0x2a <_exit>
Очищает SREG (я не уверен, что это действительно необходимо), записывает 0x9f (RAMEND) в SPL (указатель стека) и переходит к основному. Последний rjmp является излишним. (вы могли бы обещать никогда не возвращаться с основного)
00000020 <__bad_interrupt>:
20: ef cf rjmp .-34 ; 0x0 <__vectors>
Процедура прерывания по умолчанию для тех прерываний, которые не были перезаписаны в C. (те же правила, что и для __vectors)
00000022 <main>:
22: bb 9a sbi 0x17, 3 ; 23
24: c3 9a sbi 0x18, 3 ; 24
26: c3 98 cbi 0x18, 3 ; 24
28: fd cf rjmp .-6 ; 0x24 <main+0x2>
Ваш основной процесс. Плотно.
0000002a <_exit>:
2a: f8 94 cli
0000002c <__stop_program>:
2c: ff cf rjmp .-2 ; 0x2c <__stop_program>
Эти два не очень полезны. _exit, вероятно, требуется стандартом C, и __stop_program необходим для того, чтобы он работал как надо.