将 32 位值加载到 arm 程序集中的寄存器
Loading 32 bit values to a register in arm assembly
我想使用 arm 汇编将 1 个 32 位十六进制直接加载到寄存器中。
mov r1,#0x6c617669
这不能使用,因为从这条指令我们只能加载 8 位值。所以我直接从内存中加载了 32 位值。那么如何将 32 位值存储在内存中并使用 arm 汇编将其直接加载到寄存器中呢?
我试过这段代码。
.global main
main:
sub sp,sp,#4
str lr,[sp,#0]
sub sp,sp,#4
str r0,x
add sp,sp,#4
ldr lr,[sp,#0]
add sp,sp,#4
mov pc,lr
.data
x: .word 0x6c617669
但是报错如下
test1.s: Assembler messages:
test1.s:45: Error: internal_relocation (type: OFFSET_IMM) not fixed up
您有两个基本选择。您可以一次加载它或建立寄存器 8 个非零位
mov r0,#0x12000000 @ construct from 8-bit rotated immediates
orr r0,r0,#0x00340000
orr r0,r0,#0x00005600
orr r0,r0,#0x00000078
...
ldr r1,=0x12345678 @ let the assembler figure out how
...
ldr r3,myconst @ explicitly load from a nearby constant
...
myconst: .word 0x12345678
后两者是一样的,equals trick只是让汇编程序将值放在reach范围内,然后做一个pc relative load。
你可以用另一种方式,间接而不是直接:
.data
.balign 4
value: .word 0x6c617669
.text
.global main
main:
push {lr} /* save lr value on stack */
ldr r0, address_of_value /* r0 = &value */
ldr r0, [r0] /* r0 = *r0 = value */
pop {lr} /* load lr (R14) register from stack */
bx lr /* return from main using lr */
address_of_value: .word value
R0 寄存器包含 32 位值,您可以在调试此代码时看到:
(gdb) start
Temporary breakpoint 1 at 0x103ec
Starting program: /home/pi/asm/kk
Temporary breakpoint 1, 0x000103ec in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x000103e8 <+0>: push {lr} ; (str lr, [sp, #-4]!)
=> 0x000103ec <+4>: ldr r0, [pc, #8] ; 0x103fc <address_of_value>
0x000103f0 <+8>: ldr r0, [r0]
0x000103f4 <+12>: pop {lr} ; (ldr lr, [sp], #4)
0x000103f8 <+16>: bx lr
End of assembler dump.
(gdb) info registers r0
r0 0x1 1
(gdb) stepi
0x000103f0 in main ()
(gdb) stepi
0x000103f4 in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x000103e8 <+0>: push {lr} ; (str lr, [sp, #-4]!)
0x000103ec <+4>: ldr r0, [pc, #8] ; 0x103fc <address_of_value>
0x000103f0 <+8>: ldr r0, [r0]
=> 0x000103f4 <+12>: pop {lr} ; (ldr lr, [sp], #4)
0x000103f8 <+16>: bx lr
End of assembler dump.
(gdb) info registers r0
r0 0x6c617669 1818326633
此致。
根据您的处理器,您也许可以使用另一组指令(即 movw 和 movt)。例如,下面的说明不适用于使用 GCC 的 Raspberry Pi 2;然而,他们将在 Marvell Armada 370/XP 上工作;如果我没记错的话,它是 Cortex-A9
movw r1, #0x6c61
movt r1, #0x7669
...
r1 0x6c617669 1818326633
我想使用 arm 汇编将 1 个 32 位十六进制直接加载到寄存器中。
mov r1,#0x6c617669
这不能使用,因为从这条指令我们只能加载 8 位值。所以我直接从内存中加载了 32 位值。那么如何将 32 位值存储在内存中并使用 arm 汇编将其直接加载到寄存器中呢?
我试过这段代码。
.global main
main:
sub sp,sp,#4
str lr,[sp,#0]
sub sp,sp,#4
str r0,x
add sp,sp,#4
ldr lr,[sp,#0]
add sp,sp,#4
mov pc,lr
.data
x: .word 0x6c617669
但是报错如下
test1.s: Assembler messages:
test1.s:45: Error: internal_relocation (type: OFFSET_IMM) not fixed up
您有两个基本选择。您可以一次加载它或建立寄存器 8 个非零位
mov r0,#0x12000000 @ construct from 8-bit rotated immediates
orr r0,r0,#0x00340000
orr r0,r0,#0x00005600
orr r0,r0,#0x00000078
...
ldr r1,=0x12345678 @ let the assembler figure out how
...
ldr r3,myconst @ explicitly load from a nearby constant
...
myconst: .word 0x12345678
后两者是一样的,equals trick只是让汇编程序将值放在reach范围内,然后做一个pc relative load。
你可以用另一种方式,间接而不是直接:
.data
.balign 4
value: .word 0x6c617669
.text
.global main
main:
push {lr} /* save lr value on stack */
ldr r0, address_of_value /* r0 = &value */
ldr r0, [r0] /* r0 = *r0 = value */
pop {lr} /* load lr (R14) register from stack */
bx lr /* return from main using lr */
address_of_value: .word value
R0 寄存器包含 32 位值,您可以在调试此代码时看到:
(gdb) start
Temporary breakpoint 1 at 0x103ec
Starting program: /home/pi/asm/kk
Temporary breakpoint 1, 0x000103ec in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x000103e8 <+0>: push {lr} ; (str lr, [sp, #-4]!)
=> 0x000103ec <+4>: ldr r0, [pc, #8] ; 0x103fc <address_of_value>
0x000103f0 <+8>: ldr r0, [r0]
0x000103f4 <+12>: pop {lr} ; (ldr lr, [sp], #4)
0x000103f8 <+16>: bx lr
End of assembler dump.
(gdb) info registers r0
r0 0x1 1
(gdb) stepi
0x000103f0 in main ()
(gdb) stepi
0x000103f4 in main ()
(gdb) disassemble
Dump of assembler code for function main:
0x000103e8 <+0>: push {lr} ; (str lr, [sp, #-4]!)
0x000103ec <+4>: ldr r0, [pc, #8] ; 0x103fc <address_of_value>
0x000103f0 <+8>: ldr r0, [r0]
=> 0x000103f4 <+12>: pop {lr} ; (ldr lr, [sp], #4)
0x000103f8 <+16>: bx lr
End of assembler dump.
(gdb) info registers r0
r0 0x6c617669 1818326633
此致。
根据您的处理器,您也许可以使用另一组指令(即 movw 和 movt)。例如,下面的说明不适用于使用 GCC 的 Raspberry Pi 2;然而,他们将在 Marvell Armada 370/XP 上工作;如果我没记错的话,它是 Cortex-A9
movw r1, #0x6c61
movt r1, #0x7669
...
r1 0x6c617669 1818326633