寄存器弄抬、內(nèi)存氮昧、和棧
- 寄存器:
CPU 自帶的變量蓄愁。數(shù)量有限娶桦。速度最快贾节。存放的是全局變量。
如果數(shù)量較多衷畦,就需要放到內(nèi)存中栗涂。
一些寄存器:
CR0, CR2, CR3 (控制寄存器) (如:CR0的作用是切換實(shí)模式和保護(hù)模式)
D0, D1, D2, D3, D6和D7 (調(diào)試寄存器)(作為調(diào)試器的硬件支持來設(shè)置條件斷點(diǎn))
TR3, TR4, TR5, TR6 和TR? (測試寄存器)(于某些條件測試)
CS 代碼段
DS 數(shù)據(jù)段
ES 附加段
SS 堆棧段
- 內(nèi)存:
存放的也是全局變量。
- 棧:
存放局部本地變量祈争。
也是一個(gè)內(nèi)存區(qū)域斤程,只有擁有棧的特點(diǎn): 先進(jìn)后出。ARM的棧是滿遞減,棧低內(nèi)存地址最小忿墅。
實(shí)用寄存器 詳解:
SP Stack Pointer 保存棧的棧底地址扁藕,稱為棧地址。
實(shí)際操作中疚脐,棧地址會不斷變化亿柑,但是一塊代碼里面 棧地址是不變的。
PC Program Counter 存放下一條指令的地址
一般情況下棍弄,處理器執(zhí)行完一條指令后,將PC加1.順序執(zhí)行
LR Link Register 連接寄存器呼畸,
一是用來保存子程序返回地址;
二是當(dāng)異常發(fā)生時(shí)卧须,LR中保存的值等于異常發(fā)生時(shí)PC的值減4(或者減2)
因此在各種異常模式下可以根據(jù)LR的值返回到異常發(fā)生前的相應(yīng)位置繼續(xù)執(zhí)行
PSR Program Status Register 程序狀態(tài)寄存器。
程序的條件判斷準(zhǔn)則(flag), 如:結(jié)果是否為0 | 負(fù)數(shù) | 有進(jìn)位 | 溢出
指令解讀
預(yù)備知識: { }表示可選項(xiàng)瞬痘, [ ]表示間接尋址故慈, #立即數(shù)直接尋址板熊,@間接尋址
-
數(shù)據(jù)操作指令:
基本格式: op { cond }{ s } Rd, Rn, Op2
op 指令, cond條件津辩, s設(shè)置flag, op2可以是寄存器容劳、被移位的寄存器或立即數(shù)喘沿。
(如:ADD R0,R1,#5 ;R0=R1+5 #5為立即數(shù))
cond條件:
EQ 結(jié)果為0 EQual to 0
NE 結(jié)果不為0 Not Equal to 0
CS 有進(jìn)位或借位 Carry Set
HS 同CS CS unsigned Higher or Same
CC 沒有進(jìn)位或借位 Carry clear
LO 同CC unsigned LOwer
MI 結(jié)果小于0 MInus
PL 結(jié)果大于0 PLus
VS 溢出 oVerflow Set
VC 無溢出 oVerflow Clear
HI 無符號比較大于 unsigned HIgher
LS 無符號比較小于等于 unsigned Lower or Same
GE 有符號比較大于等于 signed Greater than or Equal
LT 有符號比較小于 signed Less Than
GT 有符號比較大于 signed Greater Than
LE 有符號比較小于等于 signed Less than or Equal
AL 無條件 Always,默認(rèn)
s的四種flag:
N negative 負(fù)數(shù): 結(jié)果小于0 則置1竭贩,否則置0;
Z zero 零: 結(jié)果是0則置1窄赋, 否則置0;
C carry 位移: 產(chǎn)生進(jìn)位則置1忆绰,否則0可岂,減操作則產(chǎn)生借位則置0,否則置1...
V overflow 溢出: 操作有導(dǎo)致溢出缕粹,則置1纸淮, 否則置0亚享。(有符號數(shù)運(yùn)算結(jié)果萎馅,無符號數(shù)溢出用C)
算術(shù)操作:
ADD R0, R1, R2; R0=R1+R2
ADC R0, R1, R2; R0=R1+R2 + C(carry)
SUB R0, R1, R2; R0=R1-R2
SBC R0, R1, R2; R0=R1-R2 - !C
RSB R0, R1, R2; R0=R2-R1
RSC R0, R1, R2; R0=R2-R1 - !C
邏輯操作:
AND R0, R1, R2; R0 = R1 & R2
ORR R0, R1, R2; R0 = R1 | R2
EOR R0, R1, R2; R0 = R1 ^ R2
BIC R0, R1, R2; R0 = R1 &~ R2
MOV R0, R1; R0 = R1
MVN R0, R1; R0= ~ R1
位移操作: (如:ADD R0,R1,R2,LSL#5 ;R0=R1+R2左移5位)
LSL 邏輯左移糜芳,
LSR 邏輯右移,
ASR 算術(shù)右移峭竣,
ROR 循環(huán)右移
比較操作:
CMP R1, R2 執(zhí)行 R1 - R2,并依結(jié)果設(shè)置flag晃虫,
CMN R1, R2 執(zhí)行 R1 + R2,并依結(jié)果設(shè)置flag,
TST R1, R2 執(zhí)行 R1 & R2,并依結(jié)果設(shè)置flag哲银,
TEQ R1, R2 執(zhí)行 R1 ^ R2,并依結(jié)果設(shè)置flag,
乘法操作:
MUL R4, R3, R2; R4 = R3 * R2
MLA R4, R3, R2, R1; R4 = R3 * R2 + R1
-
內(nèi)存操作指令:
基本格式:
op {cond} {type} Rd, [Rn, Op2]
Rn 是基地址寄存器滥比,用于存放基地址。cond 和上面的一樣做院。
type的四種數(shù)據(jù)類型 (不指定type,則是默認(rèn)數(shù)據(jù)類型word)
B (unsigned Byte) 無符號byte键耕,執(zhí)行時(shí)擴(kuò)展到32位,以0填充
SB (signed Byte) 有符號byte村视,僅用于LDR指令,執(zhí)行時(shí)擴(kuò)展到32位蚁孔,以符號位填充
H (unsigned Halfword) 無符號halfword讥蟆,執(zhí)行時(shí)擴(kuò)展到32位,以0填充
SH (signed Halfword) 有符號halfword瘸彤,僅用于LDR指令,執(zhí)行時(shí)擴(kuò)展到32位,以符號位填充
ARM內(nèi)存操作基礎(chǔ)指令只有兩個(gè):
LDR: (Load Register)將數(shù)據(jù)從內(nèi)存中讀出來玻靡,存到寄存器中中贝。
LDR Rt, [Rn {, #offset}]; Rt = *(Rn {+offset}), { }代表可選
LDR Rt, [Rn, #offset]!; Rt = *(Rn + offset); Rn = Rn + offset
LDR Rt, [Rn], #offset; Rt = *Rn; Rn = Rn + offset
STR: (Store Register)將數(shù)據(jù)從寄存器中讀出來,存到內(nèi)存中邻寿。
STR Rt, [Rn {, #offset}]; *(Rn {+offset}) = Rt
STR Rt, [Rn, #offset]!; *(Rn {+offset}) = Rt; Rn = Rn + offset
STR Rt, [Rn], #offset; *Rn = Rt; Rn = Rn + offset
其變種:LDRD 和 STRD 還可以操作雙字(Doubleword),即一次操作兩個(gè)寄存器
基本格式:
op {cond} Rt, Rt2, [Rn {, #offset}]
用法和上面的類似:
LDRD R4, R5, [R9, #offset]; R4 = *(R9 + offset); R5 = *(R9 + offset +4)
STRD R4, R5, [R9, #offset]; *(R9 + offset) = R4; *(R9 + offset + 4) = R5
除了基礎(chǔ)指令,還有兩個(gè)塊傳輸指令(一次操作多個(gè)寄存器):
基本格式:
op {cond}{mode} Rd {!}, reglist
Rd 是基址寄存器誊涯, 蒜撮!指定Rd變化后的值是否寫會Rd, reglist是一系列寄存器
(如:{R4-R6, R8} 就表示R4,R5,R6, R8寄存器) "{ }" "-" ","
mode 指定Rd的4種變化規(guī)律:
IA increment after, 每次傳輸后增加Rd的值段磨;
IB increment before, 每次傳輸前增加Rd的值;
DA decrement after, 每次傳輸后減少Rd的值苹支;
DB decrement before, 每次傳輸前減少Rd的值。
LDM Load multiple Rd開始連續(xù)的內(nèi)存數(shù)據(jù)存入reglist中琉用。
STM Store multiple 吧reglist中的值存入 從Rd開始的連續(xù)地址中策幼。
LDMIA R0, {R4 - R6}; 表示吧R0開始的內(nèi)存里面的值 依次存入寄存器中。
可以發(fā)現(xiàn) LDM特姐、STM 和 LDR黍氮、STR 的格式是相反的。
LDM 和 STM 是: op 內(nèi)存地址 寄存器
LDR 和 STR 是: op 寄存器 內(nèi)存地址
-
分支指令:
分為無條件分支 和 條件分支兩種沫浆。
無條件分支:
B Label; PC = Label, go to 的意思,直接跳到Label處執(zhí)行专执。
BL Label; LR = PC - 4; PC = Label
BLX Label; Label 后面的指令必須為THUMB指令 LR = PC - 4; PC = Label;
BX Rd; PC = Rd 并切換指令集(THUMB 或 ARM)
條件分支:
在該指令前,會有一條數(shù)據(jù)操作指令來設(shè)置flag攀痊,分支指令根據(jù)flag的值來決定代碼走向
CMP R0, 0; (比較指令)如果R0 == 0 則 Z = 1, 否則 Z = 0
BNE Label; (B + NE 如下)Z == 0 則跳到Label處執(zhí)行
cond flag
EQ Z=1
NE Z=0
CS C=1
HS C=1
CC C=0
LO C=0
MI N=1
PL N=0
VS V=1
VC V=0
HI C=1&Z=0 LS C=0|Z=1 GE N=V
LT N!=V
GT Z=0&N=V LE Z=1|N!=V
-
THUMB指令:
THUMB 指令是ARM指令的子集苟径,均為16位,在16位的數(shù)據(jù)總線上的傳輸效率更高蟆盐,比ARM指令更節(jié)省空間。
特點(diǎn):
1. 除了B指令外舱禽,所有的指令均無法條件執(zhí)行恩沽。
2. 桶式位移無法結(jié)合其他指令執(zhí)行。
3. 大多數(shù)指令只能使用R0 ~ R7 這八個(gè)寄存器罗心。
(例外:ADD、MOV渤闷、CMP 可以將 R8~R15 作為操作數(shù)使用。
LDR狼电、STR 可以使用 PC 或 SP 寄存器
PUSH 可以使用 LR
POP 可以使用 PC
BX 可以使用所有寄存器)
4. 指令數(shù)量減少弦蹂,如:乘法中只有MUL保留肩碟,其他都被精簡了凸椿。
5. 所有的指令默認(rèn)附帶s,即所有的THUMB指令都會設(shè)置flag髓抑。
6. 立即數(shù) 和 第二操作數(shù)使用受限。 除了位移指令吨拍、ADD网杆、SUB 其他指令形式都是 "op Rd, Rm"
7. 不支持?jǐn)?shù)據(jù)回寫握爷,即{!} 不可用了。
后記:
- 傳遞參數(shù)和返回值:
函數(shù)的前四個(gè)參數(shù) 放在 R0 ~ R3 寄存器中新啼,其他參數(shù)放在棧中刹碾。 返回值放在R0中。 - 特殊用途寄存器:
R0 ~ R3 傳遞參數(shù)與返回值迷帜;
R7 幀指針,指向母函數(shù)與被調(diào)用子函數(shù)在棧中的交界戏锹;
R9 在iOS 3.0 以前被系統(tǒng)保留;
R12 內(nèi)部過程調(diào)用寄存器荠察,dynamic linker 會用到它奈搜;
R13 SP寄存器;
R14 LR寄存器馋吗,保存返回值;
R15 PC寄存器