ARM匯編編程基礎(chǔ)之一-寄存器
ARM寄存器分為2類,普通寄存器和狀態(tài)寄存器
本文引用地址:http://m.butianyuan.cn/article/201611/322183.htm寄存器類別 | 寄存器在匯編中的名稱 | 各模式下實(shí)際訪問的寄存器 | ||||||
用戶 | 系統(tǒng) | 管理 | 中止 | 未定義 | 中斷 | 快中斷 | ||
通用寄存器和程序計(jì)數(shù)器 | R0(a1) | R0 | ||||||
R1(a2) | R1 | |||||||
R2(a3) | R2 | |||||||
R3(a4) | R3 | |||||||
R4(v1) | R4 | |||||||
R5(v2) | R5 | |||||||
R6(v3) | R6 | |||||||
R7(v4) | R7 | |||||||
R8(v5) | R8 | R8_fiq | ||||||
R9(SB,v6) | R9 | R9_fiq | ||||||
R10(SL,v7) | R10 | R10_fiq | ||||||
R11(FP,v8) | R11 | R11_fiq | ||||||
R12(IP) | R12 | R12_fiq | ||||||
R13(SP) | R13 | R13_svc | R13_abt | R13_und | R13_irq | R13_fiq | ||
R14(LR) | R14 | R14_svc | R14_abt | R14_und | R14_irq | R14_fiq | ||
R15(PC) | R15 | |||||||
狀態(tài)寄存器 | CPSR | CPSR | ||||||
SPSR | 無 | SPSR_abt | SPSR_abt | SPSR_und | SPSR_irq | SPSR_fiq |
請(qǐng)看上表的第2列,普通寄存器總共16個(gè),分別為R0-R15;狀態(tài)寄存器共2個(gè),分別為CPSR和SPSR
普通寄存器中特別要提出來的是R13、R14、R15。
R15別名PC(program counter),中文稱為程序計(jì)數(shù)器,它的值是當(dāng)前正在執(zhí)行的指令在內(nèi)存中的位置(不考慮流水線的影響,參見流水線對(duì)PC值的影響一文),而當(dāng)指令執(zhí)行結(jié)束后,CPU硬件會(huì)自動(dòng)將PC的值加上一個(gè)單位,從而使得PC的值為下一條即將執(zhí)行的指令在內(nèi)存中的位置,這樣CPU硬件就可以根據(jù)PC的值自動(dòng)完成取指的操作。正是由于有PC的存在,以及CPU硬件會(huì)自動(dòng)增加PC的值,并根據(jù)PC的值完成取指操作,才使得CPU一旦上電就永不停歇地運(yùn)轉(zhuǎn),由此可見PC寄存器對(duì)于計(jì)算機(jī)的重要性。對(duì)于我們進(jìn)行匯編程序編寫而言,PC寄存器亦是十分重要,因?yàn)楫?dāng)程序員通過匯編指令完成了對(duì)PC寄存器的賦值操作的時(shí)候,其實(shí)就是完成了一次無條件跳轉(zhuǎn),這一點(diǎn)非常重要,請(qǐng)務(wù)必要牢記。
R14別名LR(linked register),中文稱為鏈接寄存器,它與子程序調(diào)用密切相關(guān),用于存放子程序的返回地址,它是ARM程序?qū)崿F(xiàn)子程序調(diào)用的關(guān)鍵所在。下面我們用C語言中對(duì)子程序調(diào)用的實(shí)現(xiàn)細(xì)節(jié)來說明LR是如何被使用的。
1 int main(void)
2 {
3
4
5
6 }
7 int addsub(int a, int b)
8 {
9
10
11
12 }
對(duì)于上面的程序,編譯器會(huì)將第4行編譯為指令:BL addsub,將第11行編譯為指令:MOV pc, lr。(關(guān)于BL和MOV指令詳見“基本尋址模式與基本指令”)
在這里,關(guān)鍵指令BL addsub會(huì)完成2件事情:1、將子程序的返回地址(也就是第5行代碼在內(nèi)存中的位置)保存到寄存器LR中;2、跳轉(zhuǎn)到子程序addsub的第1條指令處。這樣就完成了子程序的調(diào)用。而指令MOV pc, lr則將保存在lr中的返回地址賦給pc,這樣就完成了從子程序的返回。由此可見,lr是用于存放子程序的返回地址的。
另外一個(gè)要引起注意的問題是,如果子程序又調(diào)用了孫子程序,那么根據(jù)前面的分析,在調(diào)用孫子程序時(shí),lr寄存器中的值將從子程序的返回地址變?yōu)閷O子程序的返回地址,這將導(dǎo)致從孫子程序返回子程序沒有問題,但從子程序返回父程序則會(huì)出錯(cuò)。那么這個(gè)問題如何解決呢?其實(shí),如果我們編寫的是C程序,那么我們一點(diǎn)也不用擔(dān)心,因?yàn)榫幾g器會(huì)為我們考慮一切,針對(duì)這個(gè)問題,編譯器會(huì)在孫子程序的入口處增加入棧操作將lr的值入棧,然后在孫子程序的返回處增加出棧操作,將lr的值恢復(fù),從而解決這個(gè)難題。不過我們一定要保持頭腦的清醒,因?yàn)槟阋?,我們現(xiàn)在是在編寫匯編子程序,此時(shí)編譯器已經(jīng)不能在這方面給我們提供保障,所以當(dāng)你在編寫匯編子程序的時(shí)候,發(fā)現(xiàn)該子程序還要再調(diào)用孫子程序,那么請(qǐng)你務(wù)必記住,一定要在子程序的入口處保存lr寄存器的值。
好了,現(xiàn)在輪到寄存器R13了,R13又名SP(stack pointer),中文名稱棧指針寄存器。顧名思義,它是用于存放堆棧的棧頂?shù)刂返?。也就是說,每次當(dāng)我們進(jìn)行出棧和入棧的時(shí)候,都將根據(jù)該寄存器的值來決定訪問內(nèi)存的位置(即:出入棧的內(nèi)存位置),同時(shí)在出棧和入棧操作完成后,SP寄存器的值也應(yīng)該相應(yīng)增加或減少。這里要特別說明的是,其實(shí)在32位的ARM指令集中沒有專門的入棧指令和出棧指令,所以并不是一定要用SP來作為棧指針寄存器,除了PC外,任何普通寄存器均可作為棧指針寄存器,只不過,約定俗成都使用SP罷了。我們將在“其它尋址模式與其它指令”一文中見到ARM中使用SP作為棧指針寄存器的出入棧指令。
寄存器R0-R12是普通的數(shù)據(jù)寄存器,可用于任何地方。在不涉及ATPCS規(guī)則(在“ATPCS與混合編程”一文中詳細(xì)介紹)的情況下,他們并沒有什么特別的用法。
狀態(tài)寄存器CPSR(current program status register),中文名稱:當(dāng)前程序狀態(tài)寄存器,顧名思義它是用于保存程序的當(dāng)前狀態(tài)的。那么,程序的哪些狀態(tài)是需要保存的呢?
上圖是CPSR寄存器的內(nèi)容,主要由以下部分組成:
1、條件代碼標(biāo)志位。它們是ARM指令條件執(zhí)行的依據(jù)。
N:運(yùn)算結(jié)果的最高位反映在該標(biāo)志位。對(duì)于有符號(hào)二進(jìn)制補(bǔ)碼,結(jié)果為負(fù)數(shù)時(shí)N=1,結(jié)果為正數(shù)或零時(shí)N=0;
Z:指令結(jié)果為0時(shí)Z=1(通常表示比較結(jié)果“相等”),否則Z=0;
C:當(dāng)進(jìn)行加法運(yùn)算(包括CMN指令),并且最高位產(chǎn)生進(jìn)位時(shí)C=1,否則C=0。當(dāng)進(jìn)行減法運(yùn)算(包括CMP 指令),并且最高位產(chǎn)生借位時(shí)C=0,否則C=1。對(duì)于結(jié)合移位操作的非加法/減法指令,C為從最高位最后移出的值,其它指令C通常不變
V:當(dāng)進(jìn)行加法/減法運(yùn)算,并且發(fā)生有符號(hào)溢出時(shí)V=1,否則V=0,其它指令V通常不變
2、控制位。它們將控制CPU是否響應(yīng)中斷。
I:中斷禁止位,當(dāng)I位置位時(shí),IRQ中斷被禁止
F:快中斷禁止位,當(dāng)F位置位時(shí),F(xiàn)IQ中斷被禁止
T:反映了CPU當(dāng)前的狀態(tài)。當(dāng)T位置位時(shí),處理器正在Thumb狀態(tài)下運(yùn)行;當(dāng)T位清零時(shí),處理器正在ARM狀態(tài)下運(yùn)行
3、模式位
包括M4、M3、M2、M1和M0,這些位決定了處理器的模式(關(guān)于處理器模式詳見“ARM處理器模式與異常初步”一文)。
總共有7種模式:用戶、快中斷、中斷、管理、中止、未定義、系統(tǒng),分別會(huì)用于不同的情況和異常。由此可見,不是所有模式位的組合都定義了有效的處理器模式,如果使用了錯(cuò)誤的設(shè)置,將引起一個(gè)無法恢復(fù)的錯(cuò)誤。
SPSR(saved program status register),中文名稱:保存的程序狀態(tài)寄存器
該寄存器的結(jié)構(gòu)與CPSR完全一樣,在異常發(fā)生時(shí)(關(guān)于異常,請(qǐng)參見“ARM處理器模式與異常初步”一文),由硬件自動(dòng)將異常發(fā)生前的CPSR的值存放到SPSR中,以便將來在異常處理結(jié)束后,程序能恢復(fù)原來CPSR的值。
評(píng)論