Das sieht aus wie der Dump eines Objects, also .o das noch nicht
lokatiert ist, was zu verwirrenden Dumps führen kann. Mit -r bei
objdump wirds dann etwas klarer, denn es wird Info zu den RELOCs
(Platzhalter für Symbole) ausgegeben.
Beispiel:
1 | #include <avr/io.h>
|
2 |
|
3 | uint8_t spi_exchangebyte (uint8_t data)
|
4 | {
|
5 | SPDR = data;
|
6 | while (!(SPSR & (1 << SPIF)))
|
7 | ;
|
8 | return SPDR;
|
9 | }
|
10 |
|
11 | int main;
|
übersetzt mit
$ avr-gcc foo.c -mmcu=atmega8 -Os -save-temps -c
$ avr-gcc -mmcu=atmega8 foo.o -o foo.elf
$ avr-objdump -x -d -r foo.o > foo.lss
$ avr-objdump -d -j .text -j .data -j .rodata foo.elf > foo.lst
== foo.s ==
Sieht gut aus, der RJMP geht zu einem lokalen Label (.L3) wie erwartet:
1 | spi_exchangebyte:
|
2 | out 0xf,r24
|
3 | .L3:
|
4 | sbis 0xe,7
|
5 | rjmp .L3
|
6 | in r24,0xf
|
7 | ret
|
== foo.lss ==
Das "RJMP .+0" ist verwirred, der Kommentar danach auch (auch wenn er
konsistent mit dem .+0 ist). Was wirklich geschieht zeigt der RELOC in
der nächsten Zeile: Der Sprung geht zum SBIS, also entsprechend dem .L3
wie oben auch.
1 | Disassembly of section .text:
|
2 |
|
3 | 00000000 <spi_exchangebyte>:
|
4 | 0: 8f b9 out 0x0f, r24 ; 15
|
5 | 2: 77 9b sbis 0x0e, 7 ; 14
|
6 | 4: 00 c0 rjmp .+0 ; 0x6 <spi_exchangebyte+0x6>
|
7 | 4: R_AVR_13_PCREL .text+0x2
|
8 | 6: 8f b1 in r24, 0x0f ; 15
|
9 | 8: 08 95 ret
|
== foo.lst ==
Das Zeug ist lokatiert (und gelinkt) und der Sprung wird wieder wie
erwartet dargestellt:
1 | 00000048 <spi_exchangebyte>:
|
2 | 48: 8f b9 out 0x0f, r24 ; 15
|
3 | 4a: 77 9b sbis 0x0e, 7 ; 14
|
4 | 4c: fe cf rjmp .-4 ; 0x4a <spi_exchangebyte+0x2>
|
5 | 4e: 8f b1 in r24, 0x0f ; 15
|
6 | 50: 08 95 ret
|
Also alles im grünen Bereich! Das ".-4" bedeutet: Spring zu PC -4 Bytes;
hier gezählt ab dem Byte, das auf den Sprung folgt (also ab 4e
rückwärts). Eine Endlosschleife ist also "RJMP .-2" oder "JMP .-4".