2017-08-24 55 views
0

我試圖理解這個examble約LDM和STM指令,但 我有最終結果的一個問題,這裏是例子:ARM STM/LDM指令的發佈

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

+0

寄存器總是按照從低地址到高位的數字順序傳輸。 – Jester

+0

@Jester謝謝!所以'{r1 - r3}'沒有指定任何順序?只需按照地址的數字順序? – Hector

+0

是的。還要注意,如果將堆棧操作推入並彈出(只要使用匹配模式),就會更容易。 'stmib/ldmda'實現了一個「完全遞增」的堆棧,所以它們是'stmfa/ldmfa'的別名。另請參見[使用LDM和STM的堆棧實現](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801e/dom1359731152499.html) – Jester

回答

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和數據庫使用相同的寄存器列表它基本上是堆棧推送和彈出(push和pop是stmdb和ldmia的僞代碼)。你從r1-r3開始,你完成了關於stm/ldm的指令,你回到了你開始使用的程序,它完美地工作。至於它看起來是先做了r3還是先看r1,然後在stm上使用了ia/ib/da/db。