ARM 匯編指令學(xué)習(xí):[1]ARM指令尋址方式
一、數(shù)據(jù)處理指令的操作數(shù)的尋址方式
<opcode>{<cond>}{S} <Rd>,<Rn>,<shifter_operand>
<shifter_operand>通常具有下面3種格式:
1、 立即數(shù)方式
-
#<immediate>
其中,#<immediate>=immed_8循環(huán)右移(2*rotate_imm)。
使用說明
這里需要注意關(guān)于立即數(shù)的合法性以立即數(shù)編碼的規(guī)則。
示例
MOV R0, #0xFC0
2、 寄存器方式
-
<Rm>
其中,<Rm>指定操作數(shù)所在的寄存器。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
示例
MOV R0, R1
3、 寄存器位移方式
-
<Rm>, LSL #<shift_imm>
其中:
<Rm> 為進(jìn)行邏輯左移操作的寄存器。
LSL 邏輯左移操作。
#<shift_imm> 邏輯左移位數(shù),范圍0~31。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
示例
MOV R0, R0, LSL #n ;R0=R0<<n
-
<Rm>, LSL <Rs>
其中:
<Rm> 為進(jìn)行邏輯左移操作的寄存器。
LSL 邏輯左移操作。
<Rs> 包含邏輯左移位數(shù)的寄存器。
使用說明
當(dāng)R15(PC)用作Rn、Rm、Rd及Rs時(shí),會(huì)產(chǎn)生不可預(yù)知效果(跑飛)。
示例
MOV R0, R0, LSL R2 ;R0=R0<<R2
-
<Rm>, LSR #<shift_imm>
其中:
<Rm> 為進(jìn)行邏輯右移操作的寄存器。
LSR 邏輯右移操作。
#<shift_imm> 邏輯右移位數(shù),范圍1~32,shift_imm=0時(shí)位移數(shù)為32。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
示例
MOV R0, R0, LSR #n ;R0=R0>>n
-
<Rm>, LSR <Rs>
其中:
<Rm> 為進(jìn)行邏輯右移操作的寄存器。
LSR 邏輯右移操作。
<Rs> 包含邏輯右移位數(shù)的寄存器。
使用說明
當(dāng)R15(PC)用作Rn、Rm、Rd及Rs時(shí),會(huì)產(chǎn)生不可預(yù)知效果(跑飛)。
示例
MOV R0, R0, LSR R2 ;R0=R0>>R2
-
<Rm>, ASR #<shift_imm>
其中:
<Rm> 為進(jìn)行算術(shù)右移操作的寄存器。
ASR 算術(shù)右移操作。
#<shift_imm> 算術(shù)右移位數(shù),范圍1~32,shift_imm=0時(shí)位移數(shù)為32。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
ASR與LSR的區(qū)別是:各位依次右移指定位數(shù),在左側(cè)用原符號(hào)位補(bǔ)齊,即保持符號(hào)位不變。
示例
MOV R0, R0, ASR #n
-
<Rm>, ASR <Rs>
其中:
<Rm> 為進(jìn)行算術(shù)右移操作的寄存器。
ASR 算術(shù)右移操作。
<Rs> 包含算術(shù)右移位數(shù)的寄存器。
使用說明
當(dāng)R15(PC)用作Rn、Rm、Rd及Rs時(shí),會(huì)產(chǎn)生不可預(yù)知效果(跑飛)。
示例
MOV R0, R0, ASR R2
-
<Rm>, ROR #<shift_imm>
其中:
<Rm> 為進(jìn)行循環(huán)右移操作的寄存器。
ROR 循環(huán)右移操作。
#<shift_imm> 循環(huán)右移位數(shù),范圍0~31,shift_imm=0時(shí)將執(zhí)行RRX操作。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
示例
MOV R0, R0, ROR #n
-
<Rm>, ROR <Rs>
其中:
<Rm> 為進(jìn)行循環(huán)右移操作的寄存器。
ROR 循環(huán)右移操作。
<Rs> 包含循環(huán)右移位數(shù)的寄存器。
使用說明
當(dāng)R15(PC)用作Rn、Rm、Rd及Rs時(shí),會(huì)產(chǎn)生不可預(yù)知效果(跑飛)。
示例
MOV R0, R0, ROR R1
-
<Rm>, RRX
其中:
<Rm> 為進(jìn)行移位操作的寄存器。
RRX 擴(kuò)展的循環(huán)右移操作。
使用說明
當(dāng)R15(PC)用作第一個(gè)源操作數(shù)Rn或者第二操作數(shù)Rm時(shí),操作數(shù)即為當(dāng)前指令地址加常數(shù)8。
擴(kuò)展的循環(huán)右移與循環(huán)右移的區(qū)別是:首位補(bǔ)的是進(jìn)位。(循環(huán)右移補(bǔ)的是0)
示例
MOV R0, R0, RRX
二、字及無符號(hào)字節(jié)的Load/Store指令的尋址方式
1、 立即數(shù)方式
- [<Rn>, #+/-<offset_12>]
- [<Rn>, #+/-<offset_12>]!
- [<Rn>], #+/-<offset_12>
2、 寄存器方式
- [<Rn>, +/-<Rm>]
- [<Rn>, +/-<Rm>]!
- [<Rn>], +/-<Rm>
3、 寄存器及一個(gè)移位常數(shù)方式
- [<Rn>, +/-<Rm>, <shift> #<shift_imm>]
- [<Rn>, +/-<Rm>, <shift> #<shift_imm>]!
- [<Rn>], +/-<Rm>, <shift> #<shift_imm>
每組第2個(gè)為事先訪問,第3個(gè)為事后訪問。
三、雜類Load/Store指令的尋址方式
操作數(shù)為半字(無符號(hào)數(shù)或者帶符號(hào)數(shù))數(shù)據(jù)的Load/Store指令;操作數(shù)為帶符號(hào)的字節(jié)數(shù)據(jù)的Load指令;雙字的Load/Store指令。
這類指令的語法格式為:
LDR|STR{<cond>}H|SH|SB|B <Rd>, <addressing_mode>
其中,<addressing_mode>是指令中的內(nèi)存單元的尋址方式,具體有以下6種形式:
- [<Rn>, #+/-<offset_8>]
- [<Rn>, #+/-<offset_8>]!
- [<Rn>], #+/-<offset_8>
- [<Rn>, +/-<Rm>]
- [<Rn>, +/-<Rm>]!
- [<Rn>], +/-<Rm>
- LDRH 半字無符號(hào)Load,高16位填充0
- LDRSH 半字帶符號(hào)Load,高16位填充該半字的符號(hào)位
- LDRSB 字節(jié)帶符號(hào)Load,高24位填充該字節(jié)的符號(hào)位
- LDRB 字節(jié)無符號(hào)Load,高24位填充0
STR與此上類似。
四、批量Load/Store指令的尋址方式
一條批量Load/Store指令可以實(shí)現(xiàn)在一組寄存器和一塊連續(xù)的內(nèi)存單元之間傳輸數(shù)據(jù)。
這類指令的語法格式為:
LDM|STM{<cond>}<addressing_mode> <Rn>{!}, <registers>{^}
其中,<addressing_mode>表示地址的變化方式,具體有以下4種形式:
- IA(Increment After) 事后遞增方式
- IB(Increment Before) 事先遞增方式
- DA(Decrement After) 事后遞減方式
- DB(Decrement Before) 事先遞減方式
示例
LDMIA R0, {R5-R8} ; 將內(nèi)存單元(R0)到(R0+12)4個(gè)字的數(shù)據(jù)讀取到R5~R8的4個(gè)寄存器中
LDMIB R0, {R5-R8} ; 將內(nèi)存單元(R0+4)到(R0+16)4個(gè)字的數(shù)據(jù)讀取到R5~R8的4個(gè)寄存器中
LDMDA R0, {R5-R8} ; 將內(nèi)存單元(R0-12)到(R0)4個(gè)字的數(shù)據(jù)讀取到R5~R8的4個(gè)寄存器中
LDMDB R0, {R5-R8} ; 將內(nèi)存單元(R0-16)到(R0-4)4個(gè)字的數(shù)據(jù)讀取到R5~R8的4個(gè)寄存器中
對(duì)應(yīng)于棧操作的尋址方式
- FD(Full Descending)
- ED(Empty Descending)
- FA(Full Ascending)
- EB(Empty Ascending)
根據(jù)棧指針的指向:
- 棧指針指向棧頂元素(即最后一個(gè)入棧的數(shù)據(jù)元素)時(shí)稱為FULL棧
- 棧指針指向與棧頂元素相鄰的一個(gè)可用數(shù)據(jù)單元時(shí)稱為EMPTY棧
根據(jù)數(shù)據(jù)棧的增長方向:
- 當(dāng)數(shù)據(jù)棧向內(nèi)存地址減少的方向增長時(shí),稱為DESCENDING棧
- 當(dāng)數(shù)據(jù)棧向內(nèi)存地址增加的方向增長時(shí),稱為ASCENDING棧
五、協(xié)處理器Load/Store指令的尋址方式
一條協(xié)處理器Load/Store指令可以實(shí)現(xiàn)在ARM處理器和協(xié)處理器之間傳輸數(shù)據(jù)。
這類指令的語法格式為:
<opcode>{<cond>}{L} <coproc>, <CRd>, <addressing_mode>
其中,<addressing_mode>表示地址的變化方式,具體有以下4種形式:
- [<Rn>, #+/-<offset_8>*4]
- [<Rn>, #+/-<offset_8>*4]!
- [<Rn>], #+/-<offset_8>*4
- [<Rn>], <option>
參考自《ARM體系架構(gòu)與編程》杜春雷
- 我的個(gè)人主頁:http://www.techping.cn/
- 我的個(gè)人站點(diǎn)博客:http://www.techping.cn/blog/wordpress/
- 我的CSDN博客:http://blog.csdn.net/techping
- 我的簡(jiǎn)書:http://www.itdecent.cn/users/b2a36e431d5e/timeline
- 我的GitHub:https://github.com/techping
歡迎相互follow~