SOGO論壇
  登入   註冊   找回密碼
查看: 867|回覆: 0
列印 上一主題 下一主題

[技術文章] ARM的定址模式 [複製連結]

Rank: 11Rank: 11Rank: 11Rank: 11

熱心參予論壇活動及用心回覆主題勳章 數位硬體勳章

狀態︰ 離線
跳轉到指定樓層
1
發表於 2012-7-7 09:29:16 |只看該作者 |倒序瀏覽
由於 ARM 是典型的精簡指令集處理器,因此只有載入儲存指令可以存取記憶體。然而,為了速度的原因,ARM的定址法還可分為『前置索引』與『後置索引』,索引值還可以分為『常數』或『暫存器』等,另外,針對前置索引,還有『寫回運算』可以使用。表一顯示了ARM 處理器的定址模式的一些範例。

表一、ARM 處理器的定址的範例
範例         語意         說明
LDR Rd, [Rn,+-offset]         Rd=[Rn+-offset]         前置索引
LDR Rd, [Rn,+-offset]!         Rd=[Rn+-offset] Rn=Rn+-offset         寫回運算 (!)
LDR Rd, [Rn],+-offset         Rd=[Rn] Rn=Rn+-offset         後置索引
LDR Rd, [Rn,+-Rm]         Rd=[Rn+Rm]         前置索引 (使用 Rm)
LDR Rd, [Rn,+-Rm]!         Rd=[Rn+Rm] Rn=Rn+-Rm         前置索引+寫回運算
LDR Rd, [Rn], +-Rm         Rd=[Rn] Rn=Rn+-Rm         後置索引 (使用 Rm)
LDR Rd, [Rn,+-Rm LSL Cx]         Rd=[Rn+Rm < < Cx]         移位後載入
LDR Rd, [Rn,+-Rm LSL Rx]         Rd=[Rn+Rm < < Rx]         移位後載入 (移位量由暫存器 Rx 指定)
LDR Rd, [+-offset]         Rd=[PC+-offset]         相對於程式計數器的定址

前置索引會先進行加法後,再取得記憶體內容。而後置索引則會先取得記憶體內容之後,再做加法動作。

前置索引的語法為 [Rn,+-offset] 或 [Rn,+-Rm shift Cx],其中 Rn, Rm 是暫存器,offset 是位移,而 Cx 則是移位的位元數,shift 代表移位運算,可能是左移 LSL或右移 LSR。

後置索引的語法為 [Rn],+-offset 或 [Rn],+-Rm shift Cx,由於中括號並沒有框住後置式,以此代表先取得記憶體 [Rn] 後才進行加減法。

ARM 能先進行左右移位後再進行運算,這是 ARM 的 ALU 上方的滾筒移位器的功能,這使得 ARM 可以同時執行移位與運算,不需要分成兩個指令。
常數的表示

在 ARM 的指令中,常數的載入通常是利用旋轉立即數 (<rotated_immed>) 的方式進行的,所謂的旋轉立即數,是將一個 8 位元的無號數作左 (右) 偶數位旋轉而來的,也就是說, <rotated_immed>=<immed8> ROR (2*<immed4>)。因此,0xFF、0x104、0xe0000005、0xBC00000 等都是旋轉立即數,但是 0x0101 和 0x102都不是。

因此,在 ARM CPU 中,如果我們想將 R3 的初值設為 972,因為 972 是一個旋轉立即數,因此直接使用 mov R3, #972 即可,但是若要將 R3 設為 973,則必須使用 mov R3, #972, add R3, R3, #1 等兩個指令,才能達成。這也是為了將較大範圍的常數塞入指令中,所採用的特殊設計方式。
ARM 的組合語言範例

範例一顯示了一個 ARM 的組合語言程式,該程式會將 Array 陣列中的數值相加,儲存在 Sum變數中。

範例一、ARM 的組合語言範例

; 組合語言                          ; C 語言 (對照)
    AREA    CODE                    ; void main()
    ENTRY                           ; {
    LDR R1, n                       ;   R1=n;
    LDR R2, ptr                     ;   R2=ptr;
    MOV R0, #0                      ;   R0=0;
loop:
    LDR R3, [R2], #4                ;   R3 = [R2]; R2 = R2+4;
    ADD R0, R0, R3                  ;   R0 = R0 + R3
    SUBS R1, R1, #1                 ;   R1 = R1 – 1; if (R1 > 0)
    BGT loop                        ;     goto Loop;
    STR R0, sum                     ;   sum = R0
                                    ;
    AREA DATA                       ;
sum   DCD 0                         ; int sum=0;
n     DCD 6                         ; int n=6;
ptr   DCD Array                     ; int *ptr = array;
array DCD 6, -3, 2, 9, -33, 100     ; int array[] = {6, -3, 2, 9, -33, 100};
    END                             ; }

ARM 的組合語言程式與 CPU0 相當類似,在此僅針對較特殊的部分進行說明,在範例一中,LDR R3, [R2], #4 乃是利用後置索引的方式,先做完 R3=[R2] 後,再將 R2 加上 4寫回。因此,相當於 R3=[R2];

R2=R2+4; 兩行的語義。另外,SUBS 指令當中的 S,代表運算後的結果會影響狀態暫存器 CPSR,於是後續的 BGT 才能根據CPSR的內容進行條件判斷,以決定是否要進行跳躍動作。

讀者可以比較 ARM 與 IA32 的架構,可以看出兩者有相當大的不同,不論是在暫存器或指令集上,都有明顯的差異,透過這樣的比較,應可感受到組合語言的多樣性。
喜歡嗎?分享這篇文章給親朋好友︰
               感謝作者     

請注意︰利用多帳號發表自問自答的業配文置入性行銷廣告者,將直接禁訪或刪除帳號及全部文章!
您需要登錄後才可以回覆 登入 | 註冊


本論壇為非營利自由討論平台,所有個人言論不代表本站立場。文章內容如有涉及侵權,請通知管理人員,將立即刪除相關文章資料。侵權申訴或移除要求:abuse@oursogo.com

GMT+8, 2024-6-8 14:37

© 2004-2024 SOGO論壇 OURSOGO.COM
回頂部