軟件逆向工程原理與實踐課件:ARM體系結(jié)構(gòu)_第1頁
軟件逆向工程原理與實踐課件:ARM體系結(jié)構(gòu)_第2頁
軟件逆向工程原理與實踐課件:ARM體系結(jié)構(gòu)_第3頁
軟件逆向工程原理與實踐課件:ARM體系結(jié)構(gòu)_第4頁
軟件逆向工程原理與實踐課件:ARM體系結(jié)構(gòu)_第5頁
已閱讀5頁,還剩75頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

ARM體系結(jié)構(gòu)3.1ARM基本特性3.2ARM寄存器與數(shù)據(jù)類型3.3ARM指令集3.4思考與練習(xí)

3.1ARM基本特性

在第二章中介紹的x86是一種復(fù)雜指令集計算(CISC,ComplexInstructionSetComputing)體系結(jié)構(gòu),相比之下,ARM則是一種精簡指令集計算(RISC,ReducedInstructionSetComputing)體系結(jié)構(gòu)。與x86相比,ARM體現(xiàn)出以下體系結(jié)構(gòu)特征:

(1)指令集更小,同時提供更多的通用寄存器。

(2)

ARM的內(nèi)存訪問方式與x86存在明顯差別,使用加載-存儲(LDR/STR)的內(nèi)存訪問方式,而非x86廣泛使用的MOV指令。加載和存儲的尋址均可由寄存器內(nèi)容和指令域

決定。

(3)統(tǒng)一而定長的指令域,能夠簡化對指令的解碼。

(4)在每一條數(shù)據(jù)處理指令中,同時考慮使用算數(shù)邏輯單元(ALU)和移位器(shifter),最大化對ALU和移位器的使用。

(5)引入了自增和自減尋址模式,簡化程序循環(huán)的實現(xiàn)。

(6)為增大數(shù)據(jù)吞吐率,允許加載和存儲多條指令。

(7)為增大執(zhí)行吞吐率,所有指令均支持條件執(zhí)行。

3.1.1ARM的處理器模式

ARM有七種不同的處理器模式,具體如表3-1所示。模式切換可由軟件控制,或由外部的中斷或異常處理引起。大多數(shù)應(yīng)用程序在用戶模式下運行,當(dāng)處理器處于用戶模式時,程序不能訪問一些被保護的系統(tǒng)資源,也不能進行模式切換,除非引起一個異常。處理器模式?jīng)Q定了運行于該模式下的程序能夠訪問的寄存器集合。

除用戶模式之外的其他模式均可稱為特權(quán)模式。在這些模式下,程序可以訪問所有的系統(tǒng)資源,也可以自由地切換模式。在這些特權(quán)模式中,F(xiàn)IQ、IRQ、SVC、ABT、UND這五種模式合稱為異常模式。只有在特定的異常發(fā)生時,才能進入這五種模式。每一種異常模式都有一些額外的寄存器以避免與用戶模式狀態(tài)產(chǎn)生沖突。異常的發(fā)生不會導(dǎo)致進入另一個特權(quán)模式SYS。實際上,這一特權(quán)模式是用于執(zhí)行需要訪問操作系統(tǒng)資源的特權(quán)任務(wù)的。在SYS特權(quán)模式下,能夠使用的寄存器與在用戶模式下相同。

3.1.2處理器狀態(tài)

在ARM體系結(jié)構(gòu)下,處理器狀態(tài)特指由ARM指令集或Thumb指令集所決定的狀態(tài)。Thumb指令集是ARM指令集的一個重編碼的子集。Thumb狀態(tài)指與Thumb指令集相對應(yīng)的處理器指令狀態(tài)。在Thumb狀態(tài)下,指令長度通常是ARM狀態(tài)下指令長度的一半,因此使用Thumb指令集通常能夠達到更高的代碼密度(混合使用16位/32位指令的代碼長度短于全部使用32位指令的代碼)。

Thumb指令集相對于ARM指令集受到以下兩方面限制:

(1)

Thumb代碼可能需要更多的指令完成同一項任務(wù),因此在需要最大化性能時,應(yīng)優(yōu)先使用ARM狀態(tài)的指令;

(2)

Thumb指令集不包括一些異常處理指令,因此必須使用ARM狀態(tài)指令進行頂層的異常處理。

由于以上原因,Thumb指令必須與特定版本的ARM指令配合使用。Thumb指令和ARM指令的助記符相同,在32位Thumb指令后加.W后綴以示區(qū)分。

ARM核心啟動時,多數(shù)情況進入ARM狀態(tài)并保持在此狀態(tài),直到顯式或隱式地切換到Thumb狀態(tài)。若當(dāng)前程序狀態(tài)寄存器(CPSR)中的T標(biāo)識位被置位,則處理器狀態(tài)處于Thumb狀態(tài)。

3.1.3內(nèi)存模型

ARM體系結(jié)構(gòu)采用單一的平面內(nèi)存模型,地址范圍為0~232-1。這一地址空間可以被看作230個32位字,每個字的地址都是字對齊的,即地址可以被4整除;也可以將這一地址空間看作231個16位的半字,每個半字都是半字對齊的,即地址可以被2整除。一些ARM體系結(jié)構(gòu)還向后兼容早期的226字節(jié)地址空間。

地址計算使用一般的整數(shù)指令計算。如果地址計算的結(jié)果相對于地址范圍而言出現(xiàn)了上溢或者下溢,則需要進行繞回(wraparound),即地址計算結(jié)果需要模232。

3.2ARM寄存器與數(shù)據(jù)類型

ARM具有31個通用寄存器,每個通用寄存器均為32位。在任意時刻,其中的16個通用寄存器是可見的,其他的通用寄存器用來加速執(zhí)行處理。ARM還具有6個狀態(tài)寄存器,這些狀態(tài)寄存器也是32位的,但實際上只使用其中的12位。ARM數(shù)據(jù)類型則定義了指令所能操作的操作數(shù)的長度。

3.2.1ARM寄存器

ARM的可見通用寄存器為16個,R0~R15,這些寄存器可以被任意的非特權(quán)指令所使用。這些通用寄存器可以分為三組:

(1)未分組寄存器(unbankedregister):R0~R7。這8個通用寄存器,不管處在哪個處理器模式,都指向同樣的32位物理寄存器。

(2)分組寄存器(bankedregister):R8~R14。這7個通用寄存器,會根據(jù)當(dāng)前的處理器模式,引用到不同的物理寄存器。當(dāng)我們需要使用某個具體的物理寄存器時,需要用更特殊的名稱去使用它們。

(3)程序計數(shù)器(programcounter):R15。

以下將具體介紹重要的通用寄存器及狀態(tài)寄存器的功能。

1.程序計數(shù)器

通用寄存器R15又稱程序計數(shù)器(ProgramCounter,PC)。由于ARM的流水線設(shè)計,該寄存器通常指向相對于當(dāng)前被執(zhí)行的指令的兩條指令之后,即,在ARM狀態(tài)下,PC=當(dāng)前指令地址+8字節(jié)(兩條ARM指令之后);在Thumb狀態(tài)下,PC=當(dāng)前指令地址+4字節(jié)(兩條16位Thumb指令之后)。在ARM狀態(tài)下,代碼可以直接讀寫PC寄存器。

2.鏈接寄存器

通用寄存器R14又稱鏈接寄存器(LinkRegister,LR),該寄存器通常用于在函數(shù)調(diào)用中保存返回地址。一種常見的情況是,BL指令在跳轉(zhuǎn)之前將返回地址保存在該寄存器中,即LR常保存BL指令的后一條指令的地址。典型的將R14寄存器的內(nèi)容存入PC寄存器的方法包括:

(1)

MOVPC,LR

(2)

BXLR

(3)如果被調(diào)用函數(shù)入口使用以下指令將R14的內(nèi)容壓棧:

STMFDSP!,{<其他寄存器列表>,LR}

那么使用以下指令從被調(diào)用函數(shù)返回:

LDMFDSP!,{<其他寄存器列表>,PC}

3.棧指針

通用寄存器R13又稱棧指針(StackPointer,SP),類似于x86/x64的ESP/RSP,指向棧頂位置。

4.狀態(tài)寄存器

除通用寄存器之外的所有處理器狀態(tài)都保存在狀態(tài)寄存器中。當(dāng)前的處理器狀態(tài)保存在當(dāng)前程序狀態(tài)寄存器(CurrentProgramStatusRegister,CPSR)中。此外,每一種異常模式也擁有一個被保存程序狀態(tài)寄存器(SavedProgramStatusRegister,SPSR),該寄存器在異常發(fā)生的前一刻將CPSR中的內(nèi)容保存于其中。由于SPSR僅在異常模式下起作用,因此用戶模式USR和系統(tǒng)模式SYS下不存在SPSR寄存器。某些文獻中提到的應(yīng)用程序狀態(tài)寄存器(ApplicationProgramStatusRegister,APSR),可以看作CPSR中某些字段的別名。

當(dāng)前程序狀態(tài)寄存器CPSR類似于x86/x64中的EFLAGS/RFLAGS寄存器,可以在任意處理器模式下訪問,其內(nèi)部結(jié)構(gòu)如圖3-1所示。以下分別介紹其中的重要標(biāo)識位含義。

圖3-1

CPSR寄存器的內(nèi)部結(jié)構(gòu)

1)條件代碼標(biāo)識位

CPSR中的條件代碼標(biāo)識位包括N(Negative)、Z(Zero)、C(Carry)和V(oVerflow)。指令通過測試這些標(biāo)識位的置位情況,可以決定是否執(zhí)行指令。

條件代碼標(biāo)識位不是在任意情況下都能夠更改的。實際上,ARM指令只會在以下更改條件滿足的情況下,根據(jù)計算結(jié)果對CPSR中的條件代碼標(biāo)識位進行更改:

(1)執(zhí)行一個比較操作(CMN、CMP、TEQ或TST);

(2)執(zhí)行某個算術(shù)運算操作、邏輯操作或移動操作,該操作的目標(biāo)寄存器不是R15。注意這些操作指令大多都存在兩個版本,一個是保持標(biāo)識位的版本,一個是修改標(biāo)識位的版本。修改標(biāo)識位的指令版本通常有一個后綴“S”。

在符合條件代碼標(biāo)識位的更改條件時,各條件代碼標(biāo)識位的設(shè)置操作如下。

(1)

N:設(shè)置為指令運算結(jié)果的第31位(最高位符號位)。如果指令進行有符號整數(shù)的補碼運算,則當(dāng)運算結(jié)果為負(fù)數(shù)時,N置1;當(dāng)運算結(jié)果為正數(shù)時,N置0。

(2)

Z:如果指令的運算結(jié)果為0,則置1,否則置0。對于比較運算指令,運算結(jié)果為0常代表比較結(jié)果為相等。

(3)

C:該標(biāo)識位存在四種置位方式。

①對于加法和CMN指令,如果加法運算結(jié)果產(chǎn)生一個進位(無符號上溢),則C置1,否則置0;

②對于減法和CMP指令,如果減法運算結(jié)果產(chǎn)生一個借位(無符號下溢),則C置0,否則置1;

③對于非加法、非減法指令,如果該指令配合移位操作使用,則C置為最后一個被移位器移出的位;

④對于非加法、非減法指令,且該指令沒有配合移位操作使用,則C不變。

(4)

V:該標(biāo)識位存在兩種置位方式。

①對于加法或減法運算,如果發(fā)生了有符號的上溢,則V置1;

②對于非加法、非減法運算,V不變。

2)中斷禁止位

CPSR中存在兩個中斷禁止位I和F。當(dāng)I置位時,禁止IRQ模式下的中斷;當(dāng)F置位時,禁止FIQ模式下的中斷。

3)模式位

CPSR中存在5個當(dāng)前處理器模式位M[4:0],用于指定當(dāng)前的處理器模式(USR、SVC等)。由于僅存在7個主要的處理器模式,因此并非每一種模式位取值均對應(yīng)合法的處理器模式。典型地,USR的模式位為10000,SYS的模式位為11111。

4)

ARM/Thumb處理器狀態(tài)位

ARM/Thumb處理器狀態(tài)位T用于標(biāo)識當(dāng)前執(zhí)行處于ARM狀態(tài)還是Thumb狀態(tài)。當(dāng)處于Thumb狀態(tài)時,T置1;當(dāng)處于ARM狀態(tài)時,T置0。修改此標(biāo)識位能夠?qū)崿F(xiàn)ARM狀態(tài)和Thumb狀態(tài)的切換。

5)大小端序標(biāo)識位

ARM可運行于大端序或小端序模式下。當(dāng)標(biāo)識位E置0時,為小端序;當(dāng)標(biāo)識位E置1時,為大端序。ARM在多數(shù)情況下使用小端序。

3.2.2數(shù)據(jù)類型

ARM的內(nèi)存數(shù)據(jù)類型包含以下四種:

(1)字節(jié)(Byte):8位;

(2)半字(Halfword):16位;

(3)字(Word):32位;

(4)雙字(DoubleWord):64位。

其中,半字必須與雙字節(jié)界限對齊,字必須與四字節(jié)界限對齊。需要注意的是,如果這些數(shù)據(jù)類型是無符號的,那么N位的數(shù)據(jù)值的取值范圍為0~2N-1,使用正常二進制表示;如果這些數(shù)據(jù)類型是有符號的,那么N位數(shù)據(jù)值的取值范圍為-2N-1~2N-1-1,使用二進制補碼表示。加載和存儲指令能夠?qū)⒆止?jié)、半字或字?jǐn)?shù)據(jù)在內(nèi)存和寄存器之間移動,由于寄存器是32位的,因此在從內(nèi)存加載字節(jié)或半字?jǐn)?shù)據(jù)時,會自動進行高位零填充或高位帶符號填充。

ARM指令集的指令可支持寄存器保存以下類型的數(shù)據(jù):32位指針;無符號/有符號32位整數(shù);無符號16位或8位整數(shù)(高位0擴展);有符號16位或8位整數(shù)(高位符號擴展);2個16位整數(shù)封入一個寄存器;4個8位整數(shù)封入一個寄存器;無符號/有符號64位整數(shù)保存在2個寄存器中。

3.3ARM指令集

ARM指令集主要可劃分為以下類型:分支指令、數(shù)據(jù)處理指令、狀態(tài)寄存器訪問指令、加載存儲指令、異常生成指令。ARM的指令寬度是固定的(16位或32位),根據(jù)所處的處理器狀態(tài)是ARM狀態(tài)還是Thumb狀態(tài)決定具體的指令長度。

ARM狀態(tài)下的絕大多數(shù)指令都能夠通過“指令+后綴”的形式支持條件執(zhí)行。在指令中,編碼算術(shù)條件的目的是提高代碼密度和減少分支數(shù)量,從而提高執(zhí)行效率。為了支持條件執(zhí)行,幾乎所有的ARM指令均包含一個4位的“條件域”。這4位條件域所能取得的16個數(shù)值中,一個數(shù)值(1110)代表無條件執(zhí)行,另一個數(shù)值(1111)用于一些不支持條件執(zhí)行的指令,其余14個數(shù)值代表條件執(zhí)行。如果希望ARM指令進行條件執(zhí)行,那么ARM指令就需要帶特定的條件執(zhí)行后綴,指令條件域和指令后綴之間的對應(yīng)關(guān)系如表3-2所示。

默認(rèn)情況下,ARM指令都是無條件執(zhí)行的,也就是說,當(dāng)ARM指令不帶任何條件執(zhí)行后綴時,指令的條件域是1110。當(dāng)條件域取值代表條件執(zhí)行(不等于1110和1111)時,該ARM指令僅在運算結(jié)果(CPSR條件代碼標(biāo)識位)滿足條件要求時,才執(zhí)行該ARM指令,如果運算結(jié)果不滿足條件要求,則指令相當(dāng)于NOP指令。在表3-2中,還給出了與特定執(zhí)行條件相對應(yīng)的CPSR條件代碼標(biāo)識位狀態(tài)。

在Thumb狀態(tài)下,有兩種情況下能夠支持條件執(zhí)行。第一種情況是B指令,可以使用“B<條件>”的指令形式;另一種情況是,特定的IT(if-then)指令用以支持條件執(zhí)行。其他情況下,不支持指令的條件執(zhí)行。

指令后綴除了能夠指定該指令的執(zhí)行條件外,還能指定該指令是否更新CPSR狀態(tài)寄存器。與x86指令不同的是,并非每條指令都會自動根據(jù)運算結(jié)果更新狀態(tài)寄存器。在ARM中,除了個別指令能自動更新CPSR寄存器外,對大多數(shù)指令需要用指令后綴“-S”來指明該指令會更新CPSR寄存器。例如,指令A(yù)DDS在執(zhí)行加法運算后,會根據(jù)運算結(jié)果更新CPSR中的條件代碼標(biāo)識位。

3.3.1分支指令

由于ARM的PC寄存器是通用寄存器(R15),因此ARM支持通過數(shù)據(jù)處理指令或加載指令修改PC寄存器,以達到更改控制流的目的。除此之外,標(biāo)準(zhǔn)的分支指令B可以接受24位的有符號偏移量(形如B#<imm>),實現(xiàn)向前或向后32M字節(jié)的跳轉(zhuǎn)。B指令支持條件執(zhí)行。

分支指令所指定的偏移量是24位有符號立即數(shù)。在計算目標(biāo)地址時,首先,對其進行符號擴展到32位,然后再對符號擴展的結(jié)果左移2位,此后將移位結(jié)果加到PC寄存器值之上,并將計算結(jié)果寫回PC寄存器。因此,跳轉(zhuǎn)范圍是226字節(jié),即?±32

MB。實際上目標(biāo)地址是“當(dāng)前指令地址+8字節(jié)+計算出的偏移量”。如果這一目標(biāo)地址相對地址范圍而言出現(xiàn)了上溢或者下溢,那么指令行為不可預(yù)測,因為指令行為變?yōu)橐蕾囉诘刂防@回機制(見第3.1.3節(jié))。在實際開發(fā)中,為了后續(xù)擴展地址空間的需要,程序最好不要依賴于繞回機制,因此開發(fā)時不要使用導(dǎo)致繞回的偏移量。

分支交換指令BX(BranchandeXchange)的操作數(shù)為一個寄存器,BX<reg>將操作數(shù)寄存器<reg>中的內(nèi)容復(fù)制到PC寄存器中,類似于MOVPC,<reg>。根據(jù)目標(biāo)地址的最低位(LSB)不同,該指令還能夠?qū)崿F(xiàn)對處理器狀態(tài)的切換,切換方法是:如果寄存器<reg>的第0位的值為1,則處理器狀態(tài)切換到Thumb狀態(tài)。這樣ARM狀態(tài)的調(diào)用者代碼就可以調(diào)用Thumb狀態(tài)的函數(shù),ARM狀態(tài)的被調(diào)用函數(shù)也可以返回到Thumb狀態(tài)的調(diào)用者函數(shù)。同理,也存在類似的指令能夠?qū)崿F(xiàn)從Thumb狀態(tài)到ARM狀態(tài)的分支轉(zhuǎn)換。

分支鏈接和交換指令BLX(BranchwithLinkandeXchange)的一般形式為BLX<reg|imm>。BLX

#<imm>時,BLX類似于BL(跳轉(zhuǎn)到imm地址并將返回地址保存到LR寄存器中),在此基礎(chǔ)上,處理器切換狀態(tài)。BLX

<reg>時,BLX類似于BX(跳轉(zhuǎn)到寄存器<reg>指定的地址且切換處理器狀態(tài)),在此基礎(chǔ)上,將返回地址保存到LR寄存器中。可見,通過BX和BLX指令進行分支跳轉(zhuǎn)時,若目標(biāo)寄存器的最低有效位是1,則切換到Thumb狀態(tài)。

在Thumb狀態(tài)下,比較跳轉(zhuǎn)指令(CBZ和CBNZ)形如CBZ/CBNZ<reg>,label。根據(jù)寄存器<reg>與0比較的結(jié)果決定是否跳轉(zhuǎn)到label。對于CBZ指令,比較結(jié)果為0時實施跳轉(zhuǎn);對于CBNZ指令,比較結(jié)果不為0時實施跳轉(zhuǎn)。

在Thumb-2狀態(tài)下,IT(if-then)指令模塊可以提供對小范圍跳轉(zhuǎn)的處理。IT指令用于根據(jù)特定條件來執(zhí)行緊隨其后的1~4條指令,IT指令的格式為:IT[x[y[z]]]<cond>。其中,x、y、z分別是執(zhí)行第二、三、四條指令的條件,可取的值為T(then)或E(else),對應(yīng)于條件的成立和不成立。<cond>為第一條指令的條件碼。T表示條件與<cond>匹配才能執(zhí)行,E表示條件與<cond>相反才能執(zhí)行。表3-3給出了以上分支指令的使用示例。

3.3.2數(shù)據(jù)處理指令

數(shù)據(jù)處理指令可進一步分為算數(shù)/邏輯指令、比較指令、乘法指令、前導(dǎo)零計數(shù)指令這四類,具體介紹如下。

1.算數(shù)/邏輯指令

典型的算數(shù)/邏輯運算指令如表3-4所示。其中,除了MOV和MVN指令接受一個操作數(shù)外,其他指令均接受兩個源操作數(shù)。指令對兩個源操作數(shù)進行算數(shù)或邏輯運算,并將計算結(jié)果寫入到目標(biāo)寄存器中。根據(jù)計算結(jié)果,可以選擇性地更新CPSR中的條件代碼標(biāo)識位。

這兩個源操作數(shù)中,一個總是寄存器,另一個可以是立即數(shù)、寄存器或移位操作后的寄存器值。如果操作數(shù)是移位操作后的寄存器值,那么移位的位數(shù)可以由立即數(shù)或另一個寄存器提供。我們在表3-4中描述指令時,將第一個源操作數(shù)用<Rn>表示,將第二個源操作數(shù)統(tǒng)稱為移位器操作數(shù)(用<shifter>表示),將目標(biāo)操作數(shù)用<Rd>表示。

使用移位操作后的寄存器值作為操作數(shù),這一方式稱為桶式移位器(barrelshifter),即一條指令“包含”另一條用于移位或旋轉(zhuǎn)寄存器的算數(shù)指令。例如:

MOVR1,R0,LSL#1 ;R1=R0×2

該指令將R0進行邏輯左移(LSL)1位后的結(jié)果存入寄存器R1,從而實現(xiàn)R1=R0×2的計算效果。關(guān)于此類運算中用到的邏輯左移LSL、邏輯右移LSR、循環(huán)右移ROR等移位指令的詳細(xì)用法,可參見相關(guān)的ARM體系結(jié)構(gòu)參考手冊。

在ARM中,由于PC寄存器是通用寄存器,因而算數(shù)/邏輯指令可以將運算結(jié)果直接寫入PC寄存器,從而實現(xiàn)一系列簡單的跳轉(zhuǎn)操作。

2.比較指令

ARM中存在4個比較指令:CMP、TST、CMN和TEQ。這些指令與算數(shù)/邏輯指令有同樣的指令格式。比較指令對兩個源操作數(shù)進行算數(shù)或邏輯運算,但不將運算結(jié)果寫入寄存器,而只是根據(jù)計算結(jié)果更新CPSR中的標(biāo)識位。因此,比較指令總會更新CPSR。比較指令的兩個源操作數(shù)與算數(shù)/邏輯運算的源操作數(shù)形式相同,也可以與移位操作配合使用。通常,比較指令后面緊跟一個條件分支跳轉(zhuǎn)指令。典型比較指令的功能用法如表3-5所示。

3.乘法指令

乘法指令分為兩類,一類是常規(guī)乘法,另一類是長整型乘法。對于常規(guī)乘法,只有計算結(jié)果的低32位被保存,操作數(shù)的符號位不影響結(jié)果值。長整型乘法產(chǎn)生64位的結(jié)果,保存在兩個分離的寄存器中。ARM的乘法指令不支持操作數(shù)與常量相乘。典型乘法指令的語法和語義如表3-6所示。

4.前導(dǎo)零計數(shù)指令

前導(dǎo)零計數(shù)指令CLZ(CountLeadingZeros)能夠返回操作數(shù)的二進制編碼中第一個1之前的0的個數(shù),指令格式為CLZ<reg1><reg2>。指令從最高位到最低位掃描<reg2>中的每一位,將第一個1之前的0的個數(shù)保存到目標(biāo)寄存器<reg1>中。

3.3.3狀態(tài)寄存器訪問指令

狀態(tài)寄存器訪問指令將CPSR或SPSR寄存器的內(nèi)容轉(zhuǎn)移到一個通用寄存器中,或者將一個通用寄存器的內(nèi)容轉(zhuǎn)移到CPSR或SPSR寄存器中。通過寫CPSR寄存器,可以設(shè)置條件代碼標(biāo)識位的值,設(shè)置中斷禁止位的值,或設(shè)置處理器模式。狀態(tài)寄存器訪問指令的基本用法見表3-7。以下是一個例子:

MRSR1,CPSR ;

讀取CPSR到R1

ORRR1,R1,#0x80 ;

在R1中設(shè)置CPSR的第7位I位

MSRCPSR_c,R1 ;

更新CPSR的控制位I,禁止IRQ模式下的中斷

3.3.4加載存儲指令

ARM體系結(jié)構(gòu)的內(nèi)存訪問模式是加載-存儲模式,即只有LDR/STR指令能夠訪問內(nèi)存,操作數(shù)據(jù)之前必須先將數(shù)據(jù)從內(nèi)存加載到寄存器中。

1.加載存儲單個寄存器

加載寄存器指令(LDR)將一個32位的字,或一個16位的半字,或一個8位的字節(jié)從內(nèi)存加載到寄存器中。對字節(jié)和半字的加載需要進行高位零擴展或高位符號擴展。對寄存器進行存儲的指令(STR)能夠?qū)⒓拇嫫髦械囊粋€32位的字,或一個16位的半字,或一個8位的字節(jié)存儲到內(nèi)存中。LDR和STR指令的基本用法見表3-8,表中還給出了相應(yīng)的x86/x64指令,用以說明ARM與x86指令的差異,同時也可看出ARM指令支持桶式移位的特點。

加載和存儲指令有三種尋址模式:偏移量尋址、前索引尋址和后索引尋址。這三種尋址模式均使用一個基寄存器和一個偏移量來指定內(nèi)存地址。三種尋址方式的異同見表3-9。在每一種尋址模式下,偏移量都可以是立即數(shù)或一個索引寄存器的值。如果偏移量是一個寄存器的值,那么也可以先進行桶式移位操作。

在ARM中,由于PC寄存器是通用寄存器,因而可以直接將一個32位的值加載到PC寄存器中,從而實現(xiàn)向4GB線性地址空間中的任一地址的跳轉(zhuǎn)。此外,還由于PC寄存器的通用寄存器屬性,故ARM還支持PC相對尋址,類似于x64上的RIP相對尋址,將PC寄存器作為尋址模式的基寄存器來看待。

2.加載存儲多個寄存器

加載多次指令(LDM)和存儲多次指令(STM)提供了內(nèi)存與多個通用寄存器之間的成塊數(shù)據(jù)轉(zhuǎn)移。LDM可以從給定基址寄存器加載多個字,STM可以向給定基址存儲多個寄存器的內(nèi)容。指令的通用語法為

LDM<mode><Rn>[!],{<Rm>}

STM<mode><Rn>[!],{<Rm>}

其中,<mode>是代表不同尋址模式的后綴;<Rn>表示基址寄存器;“!”為可選,意為基址寄存器會在數(shù)據(jù)轉(zhuǎn)移后更新為新的地址(稱為寫回);<Rm>表示要加載或存儲的寄存器范圍??梢钥闯?,與LDR/STR指令相比,LDM/STM指令語法所指示的數(shù)據(jù)移動方向是相反的。

這兩條指令均提供以下四種不同的尋址模式:

(1)后遞增(IncrementAfter,IA)。它是默認(rèn)的尋址模式。該模式下的起始地址是<Rn>的值,后續(xù)地址是前一地址值+4。在STM時,將寄存器列表的內(nèi)容寫入<Rn>指定的內(nèi)存位置;在LDM時,從<Rn>指定的內(nèi)存位置讀取數(shù)據(jù)到寄存器列表中。若有寫回,則向<Rn>寫回(最后一個數(shù)據(jù)加載/寫入的地址+4字節(jié))。

(2)前遞增(IncrementBefore,IB)。在該模式下,起始地址是(<Rn>+

4字節(jié)),后續(xù)地址是前一地址值?+

4。在STM時,將寄存器列表的內(nèi)容寫入(<Rn>?+

4字節(jié))的地址上;在LDM時,從(<Rn>+

4字節(jié))的地址上讀取數(shù)據(jù)到寄存器列表中。若有寫回,則向<Rn>寫回最后一個數(shù)據(jù)加載/寫入的地址。

(3)后遞減(DecrementAfter,DA)。在該模式下,起始地址是(<Rn>-

4

×?寄存器數(shù)量+4字節(jié)),后續(xù)地址是前一地址值?+4。在STM時,保存寄存器列表的內(nèi)容使得最后的地址是基地址,在LDM時,讀取從起始地址開始到基地址終止的數(shù)據(jù)到寄存器列表。若有寫回,則向<Rn>寫回(<Rn>-

4

×?寄存器數(shù)量)。

(4)前遞減(DecrementBefore,DB)。在該模式下,起始地址是(<Rn>-

4

×?寄存器數(shù)量),后續(xù)地址是前一地址值?+

4。在STM時,保存寄存器列表的內(nèi)容使得最后的地址是(基地址-

4字節(jié));在LDM時,讀取從起始地址開始到(基地址-

4字節(jié))終止的數(shù)據(jù)到寄存器列表。若有寫回,則向<Rn>寫回(<Rn>-

4

×?寄存器數(shù)量)。

LDM和STM的四種尋址模式,均可以作為指令的后綴加以指定,例如LDMDB、STMIA等也是合法指令。又因為后遞增(IA)是默認(rèn)尋址模式,因此LDM與LDMIA等價,STM與STMIA等價。

除了成塊的數(shù)據(jù)復(fù)制和移動操作外,由于返回地址和程序計數(shù)器都由通用寄存器存儲,因此函數(shù)調(diào)用的入口和出口語句均可由LDM和STM指令高效地實現(xiàn)。單個STM指令能夠在函數(shù)調(diào)用入口將寄存器內(nèi)容和返回地址壓棧,并更新棧指針;單個LDM指令能夠在函數(shù)調(diào)用出口將調(diào)用者函數(shù)的寄存器內(nèi)容從棧上取出,并加載調(diào)用者函數(shù)返回指令指針到PC寄存器,同時更新棧指針。

以下是一個例子:

subroutine

STMDB SP!,{R4-R11,LR}

LDMIASP!,{R4-R11,PC}

其中,STMDB語句保存寄存器和返回地址到棧上,LDMIA語句恢復(fù)寄存器值并返回調(diào)用者函數(shù)。

3.壓棧和出棧

PUSH指令能夠?qū)⒍鄠€寄存器的內(nèi)容壓棧;POP指令能夠?qū)m攦?nèi)容彈出到多個寄存器中。PUSH/POP指令隱式地使用棧指針SP(寄存器R13)作為基地址。在壓棧和出棧操作期間,SP(寄存器R13)的值自動調(diào)整。PUSH/POP指令的具體用法見表3-10所示。容易看出,PUSH/POP實際上就是以SP作為基地址指針的帶寫回的STMDB/LDMIA。

4.信號量指令

信號量指令SWP和SWPB用于進程同步。SWP能夠?qū)崿F(xiàn)在寄存器和內(nèi)存之間置換1個字(32位),SWPB能夠?qū)崿F(xiàn)在寄存器和內(nèi)存之間置換1字節(jié)(8位)。指令語句形如:

SWP<Rd>,<Rm>,[<Rn>]

SWPB<Rd>,<Rm>,[<Rn>]

這兩條指令能夠產(chǎn)生一個有原子性的加載和存儲操作,允許一個內(nèi)存信號量能夠在不受中斷影響的前提下被裝載和修改。SWP順序進行以下操作:

(1)加載<Rn>指定的內(nèi)存數(shù)據(jù)(4字節(jié));

(2)將寄存器<Rm>的內(nèi)容保存到<Rn>指定的內(nèi)存位置(4字節(jié));

(3)將之前被加載的內(nèi)存數(shù)據(jù)寫入寄存器<Rd>。

對于SWPB指令,順序進行以下操作:

(1)從<Rn>指定內(nèi)存加載1字節(jié)數(shù)據(jù);

(2)將寄存器<Rm>的最低8位保存到<Rn>指定的內(nèi)存位置;

(3)將之前加載的1字節(jié)數(shù)據(jù)進行從0擴展到32位,寫入寄存器<Rd>。

如果<Rd>與<Rm>指定為同一個寄存器,那么SWP指令能夠?qū)崿F(xiàn)內(nèi)存數(shù)據(jù)和寄存器數(shù)據(jù)的置換,而SWPB指令能夠?qū)崿F(xiàn)內(nèi)存字節(jié)和寄存器的最低字節(jié)數(shù)據(jù)的置換。

3.3.5異常生成指令

ARM支持五類異常:快速中斷、正常中斷、內(nèi)存終止

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論