2011-06-10 50 views
3

我想爲註釋練習的反彙編代碼塊。這是我迄今所做的:ARM反彙編器輸出:當有兩個參數而不是三個時

00000190 <mystery>: 
190: 2300  movs r3, #0   // move address 190 (offset 0) into r3 ? 
192: e004  b.n  19e <mystery+0xe> // if 19e then branch to mystery 
194: f010 0f01 tst.w r0, #1 ; 0x1  // update flags to 1 in status register 
198: bf18  it  ne    // if 198 not equal to ??? then ??? 
19a: 3301  addne r3, #1   // add to r3 if not equal to 19a offset 1? 
19c: 1040  asrs r0, r0, #1  // shift r0 right one spot (leave it in r0) 
19e: 2800  cmp  r0, #0   // compare contents of r0 against 0 ? 
1a0: d1f8  bne.n 194 <mystery+0x4> // branch to 194 if not equal to something at line 194? 
1a2: 4618  mov  r0, r3   // move r3 wholecloth into r0 
1a4: 4770  bx  lr    // branch(return from the mystery function) 
1a6: bf00  nop      // No operation 

所以,我的意見是相當不成熟,並且很可能是大規模不正確,但最重要的是我真的不明白如在190或19A說明的意思。只有兩個參數而不是三個,所以這些工作是如何工作的?

以作爲一個例子

19a: 3301  addne r3, #1 

我的這種解釋至今是:如果不等於X,然後加y以R3?什麼是X和Y?我應該使用前一行的結果嗎?如果是這樣,那麼哪個(標準三的)論點取代了?

Blah!

我願意接受我不知道我在做什麼,並且完全誤解了所有的東西。

請發出幫助!

回答

3

1)TST指令是基本相同ANDS,只是它不改變第一操作數。因此,TST r0, #1會根據(r0 & 1)的結果設置標誌。具體而言,如果結果爲零,則將設置Z(零)標誌,即,r0的位0未被設置。

2)IT代表"If-Then"。它會檢查指示的情況,並有條件地執行最多4條以下指令。在你的例子中,你只有一個條件指令,反彙編程序從IT指令中有用地提供了網元后綴(這個後綴在Thumb-2的指令本身中沒有編碼)。 NE的意思是「不相等」,但在這種情況下沒有比較,所以給出了什麼?訣竅是平等檢查檢查Z標誌,所以你可以把它看作「不是零」。所以,如果Z標誌沒有被置位,我們的ADD將被執行,即r0 確實的位0被置位。

3)類似的情況發生在CMP/BNE左右。 CMP基本上減去操作數並根據結果設置標誌。在我們的例子中,如果r0等於0,它將設置Z.接下來,BNE將測試Z標誌和分支,如果它沒有被設置(即r0是而不是等於0)。

它全部轉換爲僞C,我們得到:

r3 = 0 
goto test_loop; 
loop: 
    Z = (r0 & 1) == 0; 
    if (!Z) 
    r3 += 1; 
    r0 = r0 >> 1 
test_loop: 
    Z = (r0 - 0) == 0; 
    if (!Z) goto loop; 
    r0 = r3; 
    return; 

或者,在 「正常」 C:

r3 = 0; 
while (r0 != 0) 
{ 
    if (r0 & 1) 
    r3++; 
    r0 >>= 1; 
} 
return r3; 

看起來像它在R0位進行計數。

看一看here爲條件代碼表和他們檢查什麼標誌。 This描述如何以及何時設置標誌。


編輯:我剛纔重讀你的問題,實現你的困惑的一個來源。在這樣的行:

b.n  19e <mystery+0xe> 

一個操作數,而不是兩個。反彙編器試圖有幫助,並且不僅顯示絕對目標地址(19e),而且還顯示它作爲與最近符號的偏移量(神祕度爲190,所以19e是神祕+ 0xe)。

你需要認識到的另一件事是在ARM(以及許多其他處理器)中,設置標誌和使用標誌通常是在單獨的指令中完成的。這就是爲什麼您首先執行TST或CMP(或其他標誌設置指令),然後使用條件指令,IT或條件分支。

+0

好的,這是非常有用的 - 我怎麼知道一個條件分支已經結束? – eggonlegs 2011-06-10 13:48:18

+1

我不確定你所說的「結束」是什麼意思......條件分支(就像bne)就是那條指令,它要麼支持分支。我想你可能會談論IT指令 - 在這種情況下,它會影響到我之後有多少條指令(例如,ITTE或ITEE會影響三條指令)。無論如何,大多數(所有?)反彙編程序都會使用條件後綴標記受影響的指令,因此通常不需要計算字母數,只需查看後綴即可。 – 2011-06-10 14:03:02

+0

我剛開始閱讀這個。你解釋得很好。非常感謝 – eggonlegs 2011-06-28 06:50:17

3
190: 2300  movs r3, #0 // assign the value 0 to R3, affecting 
            // the status flags (the S suffix) 

19a: 3301  addne r3, #1 // add 1 to r3 IF the previous comparison was 
            // Not Equal to 0 

ne後綴檢查較早前由movs指令集的狀態標誌。

+3

沒錯。歡迎來到精彩的RISC世界,我們假裝通過增加標誌數量來減少指令集! – mah 2011-06-10 11:50:38

2

如果您看看ARM ARM(ARM體系結構參考手冊),它有一個更接近標誌的前面部分。與許多其他指令集不同,如果您查看ARM指令,特別是ARM的風格(而不是拇指),則每條指令的前四位都是條件位。與大多數其他處理器不同,使用arm可以有條件地執行任何指令,但大多數處理器只允許使用條件分支。條件代碼ne,nz,cs,nc等在條件代碼的早期部分中列出。因此,如果零標誌清楚,則添加addne。與大多數其他處理器不同,ARM(arm模式)允許您選擇何時銷燬/寫入標誌。大多數其他人總是會更新添加的標誌,例如,arm只會添加s,add不會添加。當你將條件執行和這些其他修飾符合併到指令時,它會變得棘手,例如它是addsne或addnes?需要反覆試驗才能發現。我會猜想addnes,但我使用這樣的組合很少,我沒有記住它。

正如已經提到的那樣,反彙編器創建了一些不可組裝的東西,輸出中還有其他項目可幫助您解碼指令。

看起來你正在看thumb2代碼,它是ARM和拇指的frankenstein混合物。所以你將有一些手臂功能和一些拇指功能,至少與binutils一些惱人的binutils主義(不要再有手臂工具鏈比較)。例如,即使我們知道許多拇指指令修改標誌而沒有作爲選項,反彙編程序通過給出添加而不是添加來顯示此標記,但您不能在拇指模式下使用添加r1,r2,因爲它會投訴,它希望您使用即使您正在修改標誌,也要添加r1,r2。 ARM正在努力推出統一的手臂/拇指組合語法,這可能已經與他們的工具鏈一起工作,但必須看到gnu工具會發生什麼。

所以我不希望能夠採取反彙編輸出,並重新組裝語法出於這兩個原因。額外的東西可以幫助你理解編碼的特定指令。

+1

統一的語法是像arm add r0,r0,r1這樣的東西,因爲你不能在拇指中使用三個寄存器,所以改變是arm組件現在允許添加r0,r1並且知道你的意思添加r0,r0,r1。被授予的手臂仍然允許添加r0,r1,r2,並且不會在拇指上工作。 – 2011-06-10 14:04:30