Entendiendo la instrucción LDR de Cortex-M con desplazamiento del pc.
Estoy examinando el código de desensamblaje de esta parte de código en C:
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
int main(void){
// Código de inicialización
while(1) {
SW1 = GPIO_PORTF_DATA_R&0x10; // Leer PF4 en SW1
// Otro código
SW2 = GPIO_PORTF_DATA_R&0x01;
}
}
El ensamblador para la línea SW1=
es (disculpa, no puedo copiar el código):
Aquí están mis preguntas:
- En la primera línea, PC = 0x00000A56 y PC + 92 = 0x00000AB2, lo cual no es igual a 0x00000AB4 que se muestra. ¿Por qué?
Investigué un poco en SO y descubrí que PC en realidad apunta a la siguiente instrucción a ser ejecutada.
Cuando se utiliza PC para lectura, hay un desplazamiento de 8 bytes en modo ARM y 4 bytes en modo Thumb.
Sin embargo, 0x00000AB4 – 0x00000A56 = 0x5E = 94, y no coincide ni con 92+8 ni con 92+4. ¿Dónde me equivoqué?
Referencia:
– https://stackoverflow.com/questions/2102921/strange-behaviour-of-ldr-pc-value
– https://stackoverflow.com/questions/24091566/why-does-the-arm-pc-register-point-to-the-instruction-after-the-next-one-to-be-e
– https://stackoverflow.com/questions/69778585/ldr-rd-label-vs-ldr-rd-pcoffset
davy.ai
Según la investigación realizada en SO, el registro PC apunta a la siguiente instrucción a ejecutar, pero hay un desplazamiento de 8 bytes en el modo ARM y 4 bytes en el modo Thumb cuando se utiliza para la lectura. Por lo tanto, la diferencia entre PC = 0x00000A56 y PC + 92 debería ser 92 + 8 = 100, no 94.
Es posible que el desensamblaje esté mostrando código Thumb, por lo que el desplazamiento sería 92 + 4 = 96. Sin embargo, ni 96 ni 100 coinciden con el número mostrado (0x00000AB4).
No está claro de dónde proviene la discrepancia, pero podría ser debido a una alineación o relleno diferente en el código de desensamblaje. También es posible que el desensamblaje no sea una representación exacta del código real que se está ejecutando.