¿Cómo funciona la instrucción ldr en ARM?

ldr r0, #0x28 

¿Qué es la instrucción thw ldr? ¿Carga una cadena desde algún desplazamiento? ¿Cómo puedo encontrar la cadena / valor que está realmente cargado?

Comentarios

  • ¿Está seguro de que ' s #0x28 y no =#0x28?

Responder

LDR carga una constante de 32 bits (LDRH (media palabra): 16 bits, LDRB (byte): 8 bits) de la memoria al registro de destino especificado (r0 en su ejemplo).

Dado que las constantes de 32 bits no se pueden codificar en códigos de operación de 32 bits (o 16 bits para instrucciones Thumb), el ensamblador almacena la constante en el segmento de texto cerca de la instrucción de referencia y luego hace referencia al valor usando ( generalmente) direccionamiento relativo a PC, es decir, algún desplazamiento de r15.

Por lo tanto, ldr es de hecho una pseudoinstrucción. El siguiente código

 .code 32 main: ldr r0, =0x12345678 bx lr 

es traducido por el ensamblador a

00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678 

Como puede vea, la constante referenciada en la instrucción ldr original se almacena en la dirección 0x8 en lugar de en la instrucción misma. La instrucción ldr en la dirección 0 luego hace referencia a este valor usando direccionamiento relativo al PC. El desplazamiento a la PC es 0 (en lugar de 8), ya que el valor real de la PC es siempre la dirección de la instrucción actual + 8; este es un efecto de la tubería del procesador ARM temprano que debe conservarse para compatibilidad.

Respuesta

Esto se puede traducir simplemente a:

r0 = 0x28; 

En el ensamblaje ARM, # marca los valores inmediatos y r0, r1, … son registros. La instrucción ldr puede tomar las siguientes formas sintácticas (la suya es la primera línea):

LDR{type}{cond} Rt, [Rn {, #offset}] ; immediate offset LDR{type}{cond} Rt, [Rn, #offset]! ; pre-indexed LDR{type}{cond} Rt, [Rn], #offset ; post-indexed LDRD{cond} Rt, Rt2, [Rn {, #offset}] ; immediate offset, doubleword LDRD{cond} Rt, Rt2, [Rn, #offset]! ; pre-indexed, doubleword LDRD{cond} Rt, Rt2, [Rn], #offset ; post-indexed, doubleword 

Responder

ldr sin = realiza cargas relativas de PC

Esto es cierto tanto para etiquetas como para números.

Pero, por supuesto, rara vez utilizará números directamente en su ensamblaje. ¿Quizás ha proporcionado algún desmontaje sin etiquetas?

Los dos siguientes funcionan en GNU GAS ARMv8. Con una etiqueta:

 ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

con un desplazamiento:

 ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

Ambos son equivalentes. El ensamblador simplemente convierte la etiqueta en el desplazamiento correcto para usted.

GitHub upstream con aserciones .

STR no tiene direccionamiento relativo a PC como LDR en ARMv8, solo tiene que calcular la dirección en registros primero: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *