AVR-GCC-Initialisierungscode

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?

Antworten (1)

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 mainFunktion auf und springt dann zu _exit(einer Endlosschleife), falls der Fall mainzurückkehrt.

Übrigens, wissen Sie, warum, wenn ich .org 0x100und .byte 0xFFzum Beispiel in OP hinzufüge, der Dump "1c4: ff ..." enthält - offensichtlich fügt Assembler die Adresse von mainzu der in angegebenen Adresse hinzu .org. Gibt es also eine Möglichkeit, den genauen Offset anzugeben?
Gibt es, aber das wäre viel zu lang für einen Kommentar. Vielleicht möchten Sie die überprüfen linker.