Estoy tratando de comprender el código de inicio del ensamblador para mi procesador ARM7TDMI. Conseguí la mayor parte, pero hay una cosa que me molesta. Encontré esta línea:
//------------------------------------------------------------------------------
/// Initializes the chip and branches to the main() function.
//------------------------------------------------------------------------------
.section .text
.global entry
entry:
resetHandler:
/* Dummy access to the .vectors section so it does not get optimized */
ldr r0, =resetVector
/* Set pc to actual code location (i.e. not in remap zone) */
ldr pc, =1f
/* Perform low-level initialization of the chip using LowLevelInit() */
1:
ldr r4, =_sstack
(...)
El que no entiendo es ldr pc, =1f
. ¿Es necesario? ¿Por qué alguien cargaría explícitamente la siguiente dirección de instrucciones? ¿No se leería automáticamente si se omitiera la línea?
ldr r0, =resetVector
/* Perform low-level initialization of the chip using LowLevelInit() */
1:
ldr r4, =_sstack
(...)
¿Cuál es la diferencia? ¿Tiene algo que ver con la vinculación o la reasignación de memoria?
EDITAR:
Bien, gracias a los comentarios a continuación, creo que lo tengo. Mirando todo el código:
125 resetHandler:
126
127 /* Dummy access to the .vectors section so it does not get optimized */
128 ldr r0, =resetVector
129
130 /* Set pc to actual code location (i.e. not in remap zone) */
131 ldr pc, =1f
132
133 /* Perform low-level initialization of the chip using LowLevelInit() */
134 1:
135 ldr r4, =_sstack
136 mov sp, r4
137 ldr r0, =LowLevelInit
138 mov lr, pc
139 bx r0
El flash tiene primero un alias de 0x0 (y se puede acceder en cualquier momento a 0x100000). La memoria RAM está en 0x200000, y se volverá a asignar a 0x0 más adelante (en la función LowLevelInit). Por lo tanto, la línea 131
carga el pc
con la dirección en flash de modo que la instrucción en la línea 135
se ejecute directamente desde flash. Si no fuera por eso, la instrucción 138
cargaría el registro lr
con el valor pc
del espacio con alias (0x0 - ...). Y debido a que LowLevelInit realiza la reasignación, sin la etiqueta 1:
, se cargaría lr
con un valor inadecuado (que apunta a la RAM después de la reasignación). Entonces, cuando regresemos de LowLevelInit ( bx r0
) terminaríamos en un lugar diferente al de donde queríamos comenzar. ¿Es eso correcto?