【问题标题】:ARM STM/LDM instructions issueARM STM/LDM 指令问题
【发布时间】:2017-08-24 10:26:57
【问题描述】:

我正在尝试理解这个关于 LDM 和 STM 指令的示例,但是 我对最终结果有疑问,这里是示例:

PRE
    r0 = 0x00009000
    r1 = 0x00000009
    r2 = 0x00000008
    r3 = 0x00000007

    STMIB r0!, {r1 - r3}

    MOV r1, #1
    MOV r2, #2
    MOV r3, #3

PRE(2)

    r0 = 0x0000900C
    r1 = 0x00000001
    r2 = 0x00000002
    r3 = 0x00000003

    LDMDA r0!, {r1 - r3}

POST
    r0 = 0x00009000
    r1 = 0x00000009
    r2 = 0x00000008
    r3 = 0x00000007

我已经这样做了,我得到了:

r0 = 0x00009000
r1 = 0x00000007
r2 = 0x00000008
r3 = 0x00000009

我不知道我错在哪里,我能想到的唯一可能是STM指令从R3开始而不是从R1开始

【问题讨论】:

  • 寄存器总是按数字顺序从低地址到高地址传输。
  • @Jester 谢谢!所以{r1 - r3} 没有指定任何顺序?只需按照地址的数字顺序?
  • 是的。另请注意,如果您将这些视为堆栈操作 push 和 pop(只要使用匹配模式),则会更容易。 stmib/ldmda 实现了“完全升序”堆栈,因此它们是 stmfa/ldmfa 的别名。另见Stack implementation using LDM and STM

标签: assembly arm


【解决方案1】:

它的实际实现方式是在大多数人无法访问的源代码中,并且没有理由假设从核心/实现到另一个它以相同的方式执行。尽管有伪代码,他们可能会从上到下而不是从下到上遍历寄存器列表,或者有一个查找表等。他们可能会做一个 8 或 4 个字的存储,而不是浪费大量的周期来做 1 个字一次。他们如何在逻辑上实际做到这一点并不重要,也不应该是为了理解。它是如何在记忆中结束的。

stmib 之前的增量

start_address = Rn + 4
end_address = Rn + (Number_Of_Set_Bits_In(register_list) * 4)
if ConditionPassed(cond) and W == 1 then
  Rn = Rn + (Number_Of_Set_Bits_In(register_list) * 4)

然后

if ConditionPassed(cond) then
address = start_address
for i = 0 to 15
if register_list[i] == 1
Memory[address,4] = Ri
address = address + 4
assert end_address == address - 4

当您使用正确的 ib 和 da 对(之前递增和之后递减)或 ia 和 db 具有相同的寄存器列表时,它基本上是堆栈推送和弹出(推送和弹出是 stmdb 和 ldmia 的伪代码)。你从 r1-r3 开始,你做了互补的 stm/ldm 指令,你得到了你开始的东西,它工作得很好。至于看起来是先做r3还是先做r1是旁观者和stm上使用的ia/ib/da/db。

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 2021-10-19
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    相关资源
    最近更新 更多