Assembly 如何将多个数据直接从标签加载到寄存器
我想知道是否有办法将存储在内存中的字数组加载到寄存器数组中 我知道ldm可以用于一次加载多个寄存器,但我的理解是,您需要为它提供一个已经包含第一个元素的寄存器 是否有一些伪指令可以提供帮助?类似于ldm=array,{r0,r1,r2}(仿照实际伪指令ldr) 提前谢谢 见: 在传统的ARM中,有四种方法可以获得标签Assembly 如何将多个数据直接从标签加载到寄存器,assembly,arm,Assembly,Arm,我想知道是否有办法将存储在内存中的字数组加载到寄存器数组中 我知道ldm可以用于一次加载多个寄存器,但我的理解是,您需要为它提供一个已经包含第一个元素的寄存器 是否有一些伪指令可以提供帮助?类似于ldm=array,{r0,r1,r2}(仿照实际伪指令ldr) 提前谢谢 见: 在传统的ARM中,有四种方法可以获得标签 target: .long 0xfeadbeef, 0xdeadfeed, 0xbaddad00 adr r0,目标 adrl r0,目标 ldr r0,=targe
target:
.long 0xfeadbeef, 0xdeadfeed, 0xbaddad00
adr r0,目标
adrl r0,目标
ldr r0,=target
子r0,pc,#(.+8-目标)
movw
movt
组合,但这不适用于您的用例
第1、2、4项基本相同。第3项将一个地址作为常量添加到文本池中,并将该地址加载到寄存器中。类似C的东西
int variable;
const int *p = &variable;
int *reg = p; /* load register from memory */
是否有一些伪指令可以提供帮助?类似于ldm=array,{r0,r1,r2}(仿照实际伪指令ldr)
此操作没有伪操作;您必须直接编写代码。
鉴于上面的“目标”定义有三个值,您可以使用
target:
.long 0xfeadbeef, 0xdeadfeed, 0xbaddad00
adr r0, target
ldm r0, {r0-r2} ; r0 as source/dest should work without write back
; ldm r0, {r1-r3} maybe safer.
伪操作未实现,因为这是“罕见的”,并且ldm
具有限制性,不支持将PC偏移量作为源。大概
; I just thunk it.
ldm pc, {r0-r2,pc} ; pc is always '8' ahead, assuming arm mode.
nop
.long arg0, arg1, arg2, routine
可能是可能的,但有限制,因为数据必须与代码一起定位,并且控制流也有限制。同样,这是一个罕见的用例,伪操作是为了更容易地将任意常量获取到通常需要的寄存器中。因此,只有ldm
命令的直接编码。可能有些ARM CPU/架构不支持将同一寄存器作为目标;回写(rN!)绝对不支持。这取决于您针对的ARM CPU的类别。使用PC
作为源代码可能更不可能在大型ARM cpu上工作。我建议使用第一个示例(rN!=r15),除非您的寄存器已经用完,并且使用的是已知的SOC/特定的ARM CPU
ldrd
指令是限制性的双字加载,但源代码具有更大的灵活性。您可以使用它加载两个值,而不需要单独的adr
。比如说,
ldr r0, r1, [pc, #offset]
但它仅限于两个寄存器。目标寄存器需要是连续的,第一个是rN,其中
N%2
为零或N甚至是在最近的ARM上有加载一对寄存器的ldp
。不确定附近的PC相对寻址模式是否可以使用ldm
。如果数据距离较远,您仍然需要在寄存器中输入标签地址。您可以使用要加载的最后一个寄存器作为地址的暂存寄存器。@PeterCordes我认为ldm
会将源代码加载到内部加载/存储管道寄存器中,因此在目标列表中使用加载将其加载是可以的。问题在于回写。从内存加载寄存器并写回结束值有点不合情理。但是OP不想这样。如果某个地方的某个ARM不支持ldm rN,{…,rN}
,我不会感到惊讶,但它应该可以工作。@artlessnoise:是的,我正在想象使用ldm
而不写回覆盖地址寄存器。如果可能的话。(由于我在第一篇评论中提到了这种可能性,PC relativeldm
是不可能的。指令使用指令字中的空格代替位移,用于加载寄存器的位图。感谢提醒,ldm需要寄存器中的指针,而不是正常的addr模式。)ldm
不是真正的伪操作,而是真正的机器指令。除非你指的是存在的意义。手册确实说回写是可选的,但也说“Rn不能是PC”。(至少在Cortex-M3上是这样,这是谷歌为ldm ldmia推出的产品)。但是,如果指定写回后缀,则reglist不能包含Rn。这意味着无需写回就可以安全地覆盖地址寄存器。(同样,Cortex-M3的文档)