如何将 .word 符号加载到 Arm 程序集中的寄存器中?
How to load a .word symbol into a register in Arm assembly?
可能是一个常见的初学者问题,,但我找不到关于几点的任何帮助。如果你有一个用 .word
定义的 32 位符号,你想将它加载到寄存器 r1
,那么常规的方法是什么?
.syntax unified
.cpu cortex-m4
.thumb
/* ... */
_allones: .word 0xffffffff
test:
/* This seems to not work as expected */
ldr r1,_allones @ Value is corrupted/misaligned?
/* Two-line solution */
ldr r1,=_allones @ Loads the address of _allones into r1, not the value itself
ldr r1,[r1] @ Get value proper
我的困惑是,当您看到像 this one 这样的教程时,其中只有 ldr r1,=_allones
用于加载 _allones
的 value(请参阅“初始化代码”,第一个列表和解释),以及我在上面链接的答案,这使得我的示例中的第一个选项看起来应该有效。 Target为Cortex-M4,Thumb模式,语法统一
FWIW ldr r1,_allones
行改为加载 _allones
的最后两个字节,然后加载内存中其地址的前两个字节,或者一些徒劳的东西,我没有仔细看在值。
一般来说,ldr r1, =sym
会将符号sym
的值加载到r1
中。 (它通过将 sym
的值组装到内存中一个非常靠近指令的称为文字池的位置来实现,以便可以使用加载指令的 pc-relative 文字形式访问它.)
但是有两种不同的方法来定义符号。它可以被定义为一个标签,如 sym:
,在这种情况下,符号的值是它标记的地址(可能直到构建的链接阶段才真正知道)。你的代码就是这种情况。但是符号也可以定义为数字常量,例如 sym EQU 12345
,在这种情况下,它的值就是数字 12345。这就是本教程中发生的事情。
所以如果你想把0xffffffff
载入r1
,两种可能性如下:
allones:
.word 0xffffffff
...
ldr r1, =allones @ now r1 contains the address where 0xffffffff is stored
ldr r1, [r1] @ load from that address
或
allones EQU 0xffffffff
...
ldr r1, =allones
当然,如果实际是0xffffffff
,那么最好只写mov r1, 0xffffffff
,或者allones equ 0xffffffff ; mov r1, allones
。 (#
在一些汇编程序中是可选的。)mov
立即数指令有一组有限的值可以用作立即数,但 0xffffffff
是其中之一。当常数具有适当的值时,某些汇编程序可能会将 ldr r1, =const
优化为 mov r1, const
。
可能是一个常见的初学者问题,.word
定义的 32 位符号,你想将它加载到寄存器 r1
,那么常规的方法是什么?
.syntax unified
.cpu cortex-m4
.thumb
/* ... */
_allones: .word 0xffffffff
test:
/* This seems to not work as expected */
ldr r1,_allones @ Value is corrupted/misaligned?
/* Two-line solution */
ldr r1,=_allones @ Loads the address of _allones into r1, not the value itself
ldr r1,[r1] @ Get value proper
我的困惑是,当您看到像 this one 这样的教程时,其中只有 ldr r1,=_allones
用于加载 _allones
的 value(请参阅“初始化代码”,第一个列表和解释),以及我在上面链接的答案,这使得我的示例中的第一个选项看起来应该有效。 Target为Cortex-M4,Thumb模式,语法统一
FWIW ldr r1,_allones
行改为加载 _allones
的最后两个字节,然后加载内存中其地址的前两个字节,或者一些徒劳的东西,我没有仔细看在值。
一般来说,ldr r1, =sym
会将符号sym
的值加载到r1
中。 (它通过将 sym
的值组装到内存中一个非常靠近指令的称为文字池的位置来实现,以便可以使用加载指令的 pc-relative 文字形式访问它.)
但是有两种不同的方法来定义符号。它可以被定义为一个标签,如 sym:
,在这种情况下,符号的值是它标记的地址(可能直到构建的链接阶段才真正知道)。你的代码就是这种情况。但是符号也可以定义为数字常量,例如 sym EQU 12345
,在这种情况下,它的值就是数字 12345。这就是本教程中发生的事情。
所以如果你想把0xffffffff
载入r1
,两种可能性如下:
allones:
.word 0xffffffff
...
ldr r1, =allones @ now r1 contains the address where 0xffffffff is stored
ldr r1, [r1] @ load from that address
或
allones EQU 0xffffffff
...
ldr r1, =allones
当然,如果实际是0xffffffff
,那么最好只写mov r1, 0xffffffff
,或者allones equ 0xffffffff ; mov r1, allones
。 (#
在一些汇编程序中是可选的。)mov
立即数指令有一组有限的值可以用作立即数,但 0xffffffff
是其中之一。当常数具有适当的值时,某些汇编程序可能会将 ldr r1, =const
优化为 mov r1, const
。