Código de inicialización AVR-GCC

Considera lo siguienteasm.S

.global main
main:
rjmp main

Compílelo y descárguelo con estos comandos:

avr-gcc -mmcu=atmega32u4 -g -o asm.elf asm.S
avr-objdump -S asm.elf

En el código de inicialización, entre otros, existe este comando:

ae: 1f be           out 0x3f, r1    ; 63

¿Por qué existe este comando?

Respuestas (1)

La secuencia de inicialización completa que veo es:

__ctors_end:
  eor   r1, r1
  out   0x3f, r1
  ldi   r28, 0xFF
  ldi   r29, 0x0A
  out   0x3e, r29
  out   0x3d, r28
  call  main
  jmp   _exit

Desglosándolo:

  eor   r1, r1
  out   0x3f, r1

El registro 0x3f es SREG, el registro de estado, que contiene bits de estado como N, Z y C, así como el bit de activación de interrupción. Este código borra el registro. El registro ya debería estar borrado en el reinicio, pero un cargador de arranque o un reinicio parcial del software puede haberlo dejado en un estado inconsistente.

  ldi   r28, 0xFF
  ldi   r29, 0x0A
  out   0x3e, r29
  out   0x3d, r28

Los puertos 0x3d y 0x3e son las partes alta y baja del puntero de pila. Este código inicializa el puntero de la pila en 0x0AFF, en la parte superior de la RAM. Esto es, nuevamente, idéntico al estado de reinicio del procesador, por lo que es más una precaución que una necesidad.

  call  main
  jmp   _exit

Esto llama a su mainfunción, luego salta a _exit(un bucle infinito) en caso de que mainregrese.

Por cierto, ¿sabe por qué si agrego .org 0x100y .byte 0xFFal ejemplo en OP, el volcado contiene ` 1c4: ff ...`? Obviamente, el ensamblador agrega la dirección de maina la dirección especificada en .org. Entonces, ¿hay alguna manera de especificar el desplazamiento exacto?
Lo hay, pero eso sería demasiado largo para un comentario. Es posible que desee comprobar el linker.