ARM寄存器結構小記

部分內容摘自Failwest大牛的《0day安全》第二版,侵刪

ARM處理器共有37個寄存器,被分為若干個組,這些寄存器包括:

  • 31個通用寄存器,包括未分組寄存器R0-R7、分組寄存器R8-R14和程序計數器( PC 指針),均為32位的寄存器。
  • 6個狀態寄存器,包括程序狀態寄存器 CPSR 和5個物理狀態寄存器 SPSR (用以異常發生時保存 CPSR 的值,異常退出時恢復 CPSR )。 這些狀態寄存器用以標識 CPU 的工作狀態及程序的運行狀態,均為32位。

具體如下表所示:

用戶模式 usr 系統模式 sys 特權模式 svc 中止模式 abt 未定義指令模式 und 外部中斷模式 irq 快速中斷模式 fiq
R0 R0 R0 R0 R0 R0 R0
R1 R1 R1 R1 R1 R1 R1
R2 R2 R2 R2 R2 R2 R2
R3 R3 R3 R3 R3 R3 R3
R4 R4 R4 R4 R4 R4 R4
R5 R5 R5 R5 R5 R5 R5
R6 R6 R6 R6 R6 R6 R6
R8 R8 R8 R8 R8 R8 R8_fiq
R9 R9 R9 R9 R9 R9 R9_fiq
R10 R10 R10 R10 R10 R10 R10_fiq
R11 R11 R11 R11 R11 R11 R11_fiq
R12 R12 R12 R12 R12 R12 R12_fiq
R13(SP) R13 R13_svc R13_abt R13_und R13_inq R13_fiq
R14(LR) R14 R14_svc R14_abt R14_und R14_inq R14_fiq
PC(R15) PC PC PC PC PC PC
CPSR CPSR CPSR CPSR CPSR CPSR CPSR
SPSR_svc SPSR_abt SPSR_und SPSR_inq SPSR_fiq

未分組寄存器 R0 - R7:

對于未分組寄存器,它們沒有被系統用于特別的用途,因此任何可采用通用寄存器的應用場合都可以使用未分組寄存器。
但需要注意一點,未分組寄存器不會因為處理器模式的改變而更改指向的寄存器,因此在所有的處理器模式下未分組寄存器都指向同一個寄存器,當中斷或異常處理造成處理器模式轉換的時候,由于不同的處理器模式使用了相同的物理寄存器,這就有可能造成寄存器中的數據被破壞。
(關于工作模式和狀態可以移步至我的另一篇文章: ARM狀態結構小記

分組寄存器 R8 - R14

對于分組寄存器,它們每一次所訪問的物理寄存器和處理器當前的運行模式有關。例如在快速中斷模式 fiq下R8-R12訪問寄存器 R8_fiq-R12_fiq ;而在其他模式下又訪問 R8_usr-R12_usr 。因此它們每個對應著兩個不同的寄存器。

對于R13(SP)、R14(LR)來說,每個寄存器對應著6個不同的物理寄存器,其中的一個是用戶模式與系統模式共用,另外5個物理寄存器對應于其他5種不同的運行模式。采用以下的記號來區分不同的物理寄存器:
R13_< mode >
R14_< mode >
其中,mode為以下幾種模式之一:usr、fiq、irq、svc、abt、und。

R13(SP)

寄存器 R13 在 ARM 指令還有著一個非常重要的作用,通常他被用作堆棧指針,當然這只是一種習慣用法,用戶也可以使用其他的寄存器作為堆棧指針,但在Thumb指令集中,某些指令強制性地要求使用R13作為堆棧指針。

由于處理器的每種運行模式均有自己福利的物理寄存器R13,使其指向該運行模式下的棧空間,這樣,當程序的運行進入異常模式時,可以將需要保護的寄存器放入R13所指向的堆棧,而當程序從異常模式返回時,則從對應的堆棧恢復,采用這種方式可以保證異常發生后程序的正常執行。

R14(LR)

R14 也稱作子程序連接寄存器(Subroutine Link Register)或連接寄存器 LR 。當執行 BL 子程序調用指令時,R14 中得到 R15 (程序計數器PC)的備份。

   0x00008d68 <+44>:    bl  0x8cd4 <func>
   0x00008d6c <+48>:    ...
   0x00008d70 <+52>:    ...

通常情況下,在匯編代碼中不會出現 R14 中產生 PC 備份的指令語句。可以簡單的理解為在執行調用的同時,將當前 PC 的指向的值 0x00008d70 減去一條指令的長度,這里是ARM工作狀態,指令長度為 0x00000004,并交由R14保存。減去一條指令的原因很簡單,不減的話返回的時候中間 0x00008d6c 處的那條指令就被跳過了。:-p

(當前執行的是 0x00008d68 處的指令,0x00008d6c 處的指令處于譯碼階段,0x00008d70 的指令處于取指階段,PC總是指向取指階段的指令。關于 ARM 處理器的流水線機制和 PC 指向的值 詳見下文。)
其他情況下,R14 也可以用作通用寄存器。與之類似,當發生中斷或異常時,對應的分組寄存器 R14_svc、R14_irq、R14_fiq、R14_abt 和 R14_und 用來保存 R15 的返回值。

每一種處理器模式在自己的物理 R14 中存放當前子程序的返回地址。當通過BL、BX 等指令調用子程序時,R14就被設置成該子程序的返回地址。例如有匯編指令如下:

  • 執行以下任意一條指令:
MOV PC,LR
BX LR
  • 在子程序入口處使用以下指令將R14存入堆棧:
STMFD SP!,{<Regs>,LR}
  • 對應的,使用以下指令可以完成子程序返回:
LDMFD SP!,{<Regs>,PC}

當發生異常中斷的時候,該模式下的特定物理R14被設置成該異常模式將要返回的地址。

R15(PC)

介紹R15之前先簡單了解一下 ARM 處理器的是流水線機制。 ARM7 處理器采用3級流水線來增加處理器指令流的速度,能提供 0.9MIPS/MHz 的指令處理速度。

ARM7 的流水線有3個階段,因此指令分3個階段執行。
⑴ 取指從存儲器裝載一條指令
⑵ 譯碼識別將要被執行的指令
⑶ 執行處理指令并將結果寫會寄存器

對于x86處理器來說,只有完成一條指令的讀取和執行后,才會執行下一條指令。這樣, PC 始終指向的正在“執行”的指令。

而對于 ARM7 來說因為是3級流水線,所以把指令的處理分為了上面所述的3個階段。所以處理時實際是這樣的: ARM 正在執行第1條指令的同時對第2條指令進行譯碼,并將第3條指令從存儲器中取出。因此 ARM7 流水線只有在取第4條指令時,第1條指令才算完成執行。繼而 ARM 的 PC 寄存器永遠指向當前執行的指令后的第二條指令,即處于取指階段的指令。

另外,在ARM狀態下,最低的兩位[1:0]為0,其他位[31:2]用于保存PC;在Thumb狀態下,最低位[0]為0,其他位 [31:1]用于保存PC;所以 R15(PC)雖然可以用作通用寄存器,但是有一些指令在使用R15時有一些特殊限制,當違反了這些限制時,程序的執行結果是未知的。

R16(CPSR)

寄存器R16用作當前程序狀態寄存器 CPSR (Current Program Status Register),可在任何運行模式下被訪問,它包括條件標志位、中斷禁止位、當前處理器模式標志位,以及其他一些相關的控制和狀態位。

每一種運行模式下又都有一個專用的物理狀態寄存器,稱為備份的程序狀態寄存器 SPSR (Saved Program Status Register),當異常發生時, SPSR 用于保存 CPSR 的當前值,從異常退出時則可由 SPSR 來恢復 CPSR 。

由于用戶模式和系統模式不屬于異常模式,他們沒有 SPSR ,當在這兩種模式下訪問 SPSR ,結果是未知的。

執行條件標志位

ARM 的執行條件與 x86 下面的標志位有些類似,系統通過對這些標志位的判斷來確定是否滿足執行條件。幾乎所有的 ARM 指令都包含一個4位的條件碼,位于指令的最高4位。條件碼共有16種,每種條件碼可用兩個字符表示,這兩個字符可以添加在指令助記符的后面和指令同時使用。

例如,跳轉指令 B 可以加上后綴 EQ 變成 BEQ 表示“相同則跳轉”,即當 CPSR 中的Z標志置位時發生跳轉。在16種條件標志碼中,只有15種可以使用,如下表所示。第十六種(1111)為系統保留,暫時不能使用。

編 碼 條件助記符 標志位 含 義
0000 EQ Z=1 相等
0001 NE Z=0 不相等
0010 CS C=1 無符號大于或等于
0011 CC C=0 無符號小于
0100 MI N=1 負值
0101 PL N=0 正值或 0
0110 VS V=1 溢出
0111 VC V=0 無溢出
1000 HI C=1 且 Z=0 無符號大于
1001 LS C=0 且 Z=1 無符號小于或等于
1010 GE N 和 V 相同 有符號大于或等于
1011 LT N 和 V 不相同 有符號小于
1100 GT Z=0 且 N 等于 V 有符號大于
1101 LE Z=1 且 N 不等于 V 有符號小于或等于
1110 AL 任意 無條件執行(不推薦使用)
1111 NV 任意 從不執行(不要使用)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎入門學習匯編語言》系列視頻的筆記,在此感謝他和像他一樣...
    Gibbs基閱讀 37,421評論 8 114
  • 算術和邏輯指令ADC : 帶進位的加法(Addition with Carry)ADC{條件}{S} <dest...
    luffier閱讀 3,823評論 0 3
  • 不知道為什么睡著睡著就睡不著了,我分明是很困啊!今天是室友生日翻來以前的照片,翻著翻著就睡不著了!講道理我也沒怕什...
    不愛幻想的蘑菇閱讀 135評論 0 0
  • 人說時光如逝,轉眼間就是白云蒼狗,細想來,你離開我的這幾年,大抵便是如此沉淀幾年,我以為我已經可以把一些想法寫出來...
    沙曼德閱讀 395評論 13 15
  • 寫文之前,剛跑了個十公里。因為要準備下個月的馬拉松,就按手機里的APP備賽訓練。我平時跑量并不大,成績也很普通,但...
    彼得貓烏金閱讀 1,739評論 0 3