Folgendes berücksichtigenasm.S
.global main
main:
rjmp main
Kompilieren und sichern Sie es mit diesen Befehlen:
avr-gcc -mmcu=atmega32u4 -g -o asm.elf asm.S
avr-objdump -S asm.elf
Im Initialisierungscode gibt es unter anderem diesen Befehl:
ae: 1f be out 0x3f, r1 ; 63
Warum gibt es diesen Befehl?
Die vollständige Initialisierungssequenz, die ich sehe, ist:
__ctors_end:
eor r1, r1
out 0x3f, r1
ldi r28, 0xFF
ldi r29, 0x0A
out 0x3e, r29
out 0x3d, r28
call main
jmp _exit
Brechen sie ab:
eor r1, r1
out 0x3f, r1
Register 0x3f ist SREG – das Statusregister, das Statusbits wie N, Z und C sowie das Interrupt-Enable-Bit enthält. Dieser Code löscht das Register. Das Register sollte beim Zurücksetzen bereits gelöscht sein, aber ein Bootloader oder ein teilweiser Software-Reset hat es möglicherweise in einem inkonsistenten Zustand hinterlassen.
ldi r28, 0xFF
ldi r29, 0x0A
out 0x3e, r29
out 0x3d, r28
Die Ports 0x3d und 0x3e sind die hohen und niedrigen Teile des Stapelzeigers. Dieser Code initialisiert den Stapelzeiger auf 0x0AFF oben im RAM. Dies ist wiederum identisch mit dem Reset-Zustand des Prozessors, daher ist dies eher eine Vorsichtsmaßnahme als eine Notwendigkeit.
call main
jmp _exit
Dies ruft Ihre main
Funktion auf und springt dann zu _exit
(einer Endlosschleife), falls der Fall main
zurückkehrt.
Igor Liferenko
.org 0x100
und.byte 0xFF
zum Beispiel in OP hinzufüge, der Dump "1c4: ff ..." enthält - offensichtlich fügt Assembler die Adresse vonmain
zu der in angegebenen Adresse hinzu.org
. Gibt es also eine Möglichkeit, den genauen Offset anzugeben?TurboJ
linker
.