ARM STM / LDM指令问题

时间:2017-08-24 10:26:58

标签: assembly arm

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

!new[] { ".ext", ".test", ".admin" }.Any(c => ui.Title.ToLower().Contains(c))
!new[] { ".ext", ".test", ".admin" }.Any(c => ui.Department.ToLower().Contains(c))
!new[] { ".ext", ".test", ".admin" }.Any(c => ui.Company.ToLower().Contains(c))
!new[] { ".ext", ".test", ".admin" }.Any(c => ui.Username.ToLower().Contains(c))

我这样做了,我得到了:

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

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

1 个答案:

答案 0 :(得分:0)

它是如何实际实现的是大多数人无法访问的源代码,并且没有理由假设从核心/实现到另一个它以相同的方式执行它。尽管有伪代码,他们可能会从上到下走到寄存器列表而不是从下到上或者有一个查找表等等。他们可能会做一个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与相同的寄存器列表时,它基本上是堆栈push和pop(push和pop是stddb和ldmia的伪代码)。你从r1-r3开始,你做了stm / ldm的说明,你得到了你的开始,它完美地运作了。至于它是否首先完成r3或r1首先是在旁观者的眼中,而是在stm上使用的ia / ib / da / db。