2011-07-08 53 views
2

我一直在緩慢回升的事情了組裝。我正在研究Canon Rebel T1i,這是我想了解的代碼流程圖的一小部分。據我所知,我相信相機具有132MHz ARM V5處理器:解釋跳轉表/分支表

http://i.imgur.com/PtWC9.png

我已搜查谷歌的試圖理解跳轉表是如何工作的,而且不管我讀了多少,我就可以」底部把東西連接在一起來理解它。我瞭解跳轉表與案例陳述類似,但我不明白它是如何在表格中移動的。

例如:在這個例子中,只有一個CMP操作,所以我不明白這是怎麼工作的準確。任何幫助將不勝感激!!

回答

5

我不認爲你有足夠的信息在屏幕上打出瞭解它是如何連接到你的問題。但總的來說跳轉表...

在C想起功能的陣列,和你有函數的數組初始化中的每個元素,在某一點後您的代碼對一些決定,並使用索引來選擇一個這些功能。正如你提到的case語句,可以這樣實現,但這不是規則的例外,全部取決於switch中使用的變量以及case語句中元素的大小/寬度/性質。

你一直在拿起程序集,所以你理解寄存器,與寄存器進行數學運算,在寄存器中存儲東西等等。程序計數器可以被許多指令用作另一個寄存器,不同之處在於當你寫一些東西它會改變接下來執行的指令。

讓我們嘗試一個case語句例如:

switch(bob&3) 
{ 
    case 0: ted(); break; 
    case 1: joe(); break; 
    case 2: jim(); bob=2; break; 
    case 3: tim(); bob=7; break; 
} 

什麼,你可以(可能不會)做的是:

casetable: 
    .word a 
    .word b 
    .word c 
    .word d 

    caseentry: 
     ldr r1,=bob 
     ldr r0,[r1] 
     ldr r2,=casetable 
     and r0,#3 
     ldr pc,[r2,r0,lsl #2] 

    a: 
     bl ted 
     b caseend 
    b: 
     bl joe 
     b caseend 
    c: 
     bl jim 
     mov r0,#2 
     ldr r1,=bob 
     str r0,[r1] 
     b caseend 
    d: 
     bl tim 
     mov r0,#7 
     ldr r1,=bob 
     str r0,[r1] 
     b caseend 

    caseend: 

所以四個字標籤casetable後:是地址,其中代碼從每個案例開始,case0從a開始:case1代碼從b開始:依此類推。我們需要做的是採用switch語句使用的變量,並以數學方式計算表中項目的地址。然後我們需要將表中的地址加載到程序計數器中。寫入程序計數器與執行跳轉相同。

所以C樣品intentially雕琢,使這個容易。首先將bob變量的內容加載到r0中。它與3.跳轉表中的項目是32位地址,或4個字節,所以我們需要乘以r0乘以4以獲得表中的偏移量。 2左移與4乘以相同。我們需要在跳轉表的基地址中添加r0 < < 2。所以基本上,我們計算address_of(casetable)+((BOB & 3)< < 2)在該計算的地址讀取存儲和值加載到程序計數器中。

隨着臂(你所提到的,這是臂)可以做很多的這一個指令:

ldr pc,[r2,r0,lsl #2] 

載入到寄存器PC機的存儲器位置的內容[R2 +(R0 < < 2) ]。 r2是個案表的地址,r0是bob & 3。

基本上,跳轉表歸結爲以數學方式計算地址表中的偏移量。地址表是您要跳轉/分支的地址,具體取決於數學運算中使用的參數之一,在上面的示例中,bob是該變量。而地址a,b,c,d是我想根據bob的內容選擇的地址選項。有很多有趣和有趣的方法可以做到這一點,但這一切都歸結爲在運行時計算要分支到的地址,並將該地址推入程序計數器,以便使特定處理器執行基本上是一個跳躍

注意另一個,也許更容易閱讀的方式來計算和跳躍在我的例子是:

mov r3,r0,lsl #2 
    add r3,r2 
    bx r3 

支持拇指使用BX指令與通常寄存器的核心,通常你看到BX LR返回從分支鏈接(子例程)調用。 bx lr表示pc = lr。 bx r3表示pc = r3。

我希望這是你所問的,如果我誤解了這個問題,請詳細說明。

編輯:在您的屏幕截圖代碼

展望。

cmp r0,#4 
addls pc,pc,r0,lsl #2 

可選數學(ADDL的添加如果小於或相同)計算基於所述程序計數器本身加上偏移R0倍4的新程序計數器的值(跳轉表是存儲在程序計數器的計算)。對於ARM處理器,在執行時,程序計數器提前兩個指令。所以,這些代碼兩行和我的例子的一部分混合:

cmp r0,#4 
addls pc,pc,r0,lsl #2 
ldr pc,=a 
ldr pc,=b 
ldr pc,=c 
ldr pc,=d 
... 

此時的ADDL在執行程序計數器包含地址爲LDR PC,= B指令。所以如果r0包含一個0,那麼0 = 0,那麼pc加0將分支到ldr pc,= b指令,那麼該指令引起一個分支到b:標籤。如果r0在addls時包含1,那麼您將執行ldr pc,然後執行= c指令,依此類推。你可以用這種方法制作一張桌子。還要注意,由於add是有條件的,如果條件沒有發生,你將在addls之後執行第一條指令,所以也許你希望它是一個無條件的分支來分支表,或者向後分支一個循環或者它可能是讓你陷入第一次跳躍,或者我上面做的是讓它跳到另一個地方。因此,要了解發生了什麼,您需要舉例說明遵循addls的指示,以確定可能的跳轉表目的地。

+0

謝謝!這一切現在都完成了,特別感謝你解釋說ADDLS是「添加不足或相同」,現在就有道理。 – Coutts