Arm寄存器介绍及汇编基础

一、ARM处理器支持7种工作模式

① 用户模式(USR): 用于正常执行程序(The normal ARM program execution state)

② 快速中断模式(FIQ): 用于高速数据传输(Designed to support a data transfer or channel process)

③ 外部中断模式(IRQ): 用于通常的中断处理(Used for general-purpose interrupt handling)

④ 管理模式(SVC): 操作系统使用的保护模式(Protected mode for the operating system)

⑤ 数据访问终止模式(ABT): 当数据或指令预取终止时进入该模式(Entered after a data or instruction prefetch abort)

⑥ 系统模式(SYS): 运行具有特权的操作系统任务(A privileged user mode for the operating system)

⑦ 未定义指令异常模式(UND): 当未定义的指令执行时进入该模式(Entered when an undefined instruction is executed)

注:ARM微处理器的运行模式可以通过软件改变(修改CPSR后5位),也可以通过中断或者异常处理改变

二、ARM寄存器

① ARM微处理器共有37个32位处理器,其中31个位通用寄存器,6个为状态寄存器

Arm寄存器介绍及汇编基础

注:其中带阴影的寄存器为各个模式私有的寄存器,未带阴影为各模式共有寄存器

② ARM寄存器分类

(1)不分组寄存器:R0~R7

(2)分组寄存器:R8~R14(R13通常用作栈指针SP,R14通常用作子程序链接寄存器LR)

(3)程序计数器:R15(PC)

③ APCS(ARM Procedure Call Standard)对ARM各个寄存器的命名

Arm寄存器介绍及汇编基础

④ ARM状态寄存器(CPRS):(SPSR是CPSR的备份,只有异常模式才有)

Arm寄存器介绍及汇编基础

(1)Mode bits(模式位)

0b10000:USR

0b10001:FIQ

0b10010:IRQ

0b10011:SVC

0b10111:ABT

0b11011:SYS

0b11111:UND

(2)T:工作状态位(Thumb:1  ARM:0)

(3)F:FIQ中断禁止位(禁止:1  允许:0)

(4)I:IRQ中断禁止位(禁止:1  允许:0)

(5)NZCV:条件标志位

三、ARM寻址方式

① 立即数寻址:操作数本身就在指令中

ADD R0, R1, #0x01
ADD R0, R0, #0x3f

② 寄存器寻址:利用寄存器中的数值作为操作数

ADD R0, R1, R2

③ 寄存器间接寻址:以寄存器中的值作为地址,而操作数本身存放在存储器中

ADD R0, R1, [R2]
LDR R0, [R2]

④ 基址变址寻址:将寄存器中的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址

LDR R0, [R1, #]
LDR R0, [R1, #]!
LDR R0, [R1], #
LDR R0, [R1, R2]

⑤ 多寄存器寻址:一条指令可以完成多个寄存器值得传送

LDMIA R0, {R1, R2, R3, R4}

⑥ 相对寻址:以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址

BL NEXT
...
NEXT:
...
MOV PC, LR

⑦ 堆栈寻址:

stmfd sp!, {r1-r3};
ldmfd sp!, {r0-r12, lr, pc}^

四、ARM汇编指令介绍

1. 程序状态寄存器访问指令

(1)MRS指令:用于将程序状态寄存器的内容传送到通用寄存器中

格式: MRS{条件} 通用寄存器, 程序状态寄存器(CPSR或SPSR)

MRS     R0, CPSR                ; 复制 CPSR 到 R0 中
MRS R0, SPSR ; 复制 SPSR 到 R0 中

(2)MSR指令:用于将普通寄存器的内容传送到程序状态寄存器的特定域

格式: MSR{条件}  程序状态寄存器(CPSR或SPSR)_<域>, 通用寄存器

MSR     CPSR, R0                ; 复制 R0 到 CPSR 中
MSR SPSR, R0 ; 复制 R0 到 SPSR 中
MSR CPSR_flg, R0 ; 复制 R0 的标志位到 CPSR 中
MSR CPSR_flg, #<< ; 复制(立即值)标志位到 CPSR 中

(3)CPSR是当前的程序状态寄存器(Current Program Status Register),而 SPSR 是保存的程序状态寄存器(Saved Program Status Register)。每个有特权的模式都有自己的 SPSR,可获得的 PSR 有:

  • CPSR_all - 当前的
  • SPSR_svc - 保存的,SVC(32) 模式
  • SPSR_irq - 保存的,IRQ(32) 模式
  • SPSR_abt - 保存的,ABT(32) 模式
  • SPSR_und - 保存的,UND(32) 模式
  • SPSR_fiq - 保存的,FIQ(32) 模式

(4)改变模式代码:

MRS     R0, CPSR_all            ; 复制 PSR
BIC R0, R0, #&1F ; 清除模式位
ORR R0, R0, #new_mode ; 把模式位设置为新模式
MSR CPSR_all, R0 ; 写回 PSR,变更模式

2. 寄存器装载和存储指令

(1)LDR/STR指令:用于寄存器和存储器之间数据的传送

格式:LDR/STR{条件} Rd, <地址>

  LDR/STR{条件}B Rd, <地址>

备注:‘B’,表示只装载或存储一个单一的字节

STR    Rd, [Rbase]          存储 Rd 到 Rbase 所包含的有效地址。
STR Rd, [Rbase, Rindex] 存储 Rd 到 Rbase + Rindex 所合成的有效地址。
STR Rd, [Rbase, #index] 存储 Rd 到 Rbase + index 所合成的有效地址。
index 是一个立即值。
例如,STR Rd, [R1, #] 将把 Rd 存储到 R1+。
STR Rd, [Rbase, Rindex]! 存储 Rd 到 Rbase + Rindex 所合成的有效地址,
并且把这个新地址写回到 Rbase。
STR Rd, [Rbase, #index]! 存储 Rd 到 Rbase + index 所合成的有效地址,
并且并且把这个新地址写回到 Rbase。
STR Rd, [Rbase], Rindex 存储 Rd 到 Rbase 所包含的有效地址。
把 Rbase + Rindex 所合成的有效地址写回 Rbase。
STR Rd, [Rbase, Rindex, LSL #]
存储 Rd 到 Rbase + (Rindex * ) 所合成的有效地址。
STR Rd, place 存储 Rd 到 PC + place 所合成的有效地址。

(2)LDM/STM指令:装载和存储多个字的数据从/到内存(LDM/STM 的主要用途是把需要保存的寄存器复制到栈上)

格式:LDM/STM{条件}{类型} Rn{!}, <寄存器列表>{^}

① 类型

IA: 每次传送后地址加1
IB: 每次传送前地址减1
DA: 每次传送后地址减1
DB: 每次传送前地址减1
FD: 满递减堆栈
ED: 空递减堆栈
FA: 满递增堆栈
EA: 空递增堆栈

②{!}:可选后缀,选用后,当数据传送完毕之后,将最后的地址写入基地址寄存器,否则基地址寄存器的内容不变

③{^}:可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀表示:除了正常的数据传送之外,还要将SPSR复制到CPSR

STMFD R13!, {R0, R4-R12, LR}    ;寄存器->存储器
LDMFD R13!, {R0, R4-R12, LR} ;存储器->寄存器

(3)SWP指令:在存储器和寄存器之间交换数据

SWP{条件}{B} 目的寄存器, 源寄存器1,[源寄存器2]

注:将源寄存器2所指向的存储器数据传送到目的寄存器,同时将源寄存器1的内容存储到源寄存器2所指向的存储器中。

SWP R0, R1, [R2]
SWP R0, R0, [R1]

3. 算术和逻辑指令

(1)ADC指令:带进位的加法

格式:ADC{条件}{S} 目的寄存器 操作数1 操作数2

  ADDS    R0, R4, R8              ; 加低端的字
ADCS R1, R5, R9 ; 加下一个字,带进位
ADCS R2, R6, R10 ; 加第三个字,带进位
ADCS R3, R7, R11 ; 加高端的字,带进位

注:{S}更改进位标志

(2)ADD指令:用于将两个操作数相加,并将结果存放到目的寄存器中

格式:ADD{条件}{S} 目的寄存器 操作数1 操作数2

ADD     R0, R1, R2              ; R0 = R1 + R2
ADD R0, R1, # ; R0 = R1 + 256
ADD R0, R2, R3,LSL# ; R0 = R2 + (R3 << 1)

(3)AND指令:逻辑与

格式:AND{条件}{S} 目的寄存器 操作数1 操作数2

AND     R0, R0, #              ; R0 = 保持 R0 的位 0 和 1,丢弃其余的位。

(4)BIC指令:位清除

格式:BIC{条件}{S} 目的寄存器 操作数1 操作数2

BIC     R0, R0, #%          ; 清除 R0 中的位 0、1、和 3。保持其余的不变。

(5)EOR指令:逻辑异或

格式:EOR{条件}{S} 目的寄存器 操作数1 操作数2

EOR     R0, R0, #              ; 反转 R0 中的位 0 和 1

(6) MOV指令:完成从另一个寄存器、被移位寄存器或将另一个立即数加载到目的寄存器

格式:MOV{条件}{s} 目的寄存器, 源操作数

MOV     R0, R0                  ; R0 = R0... NOP 指令
MOV R0, R0, LSL#3 ; R0 = R0 * 8
MOV PC, R14 ; 退出到调用者
MOVS PC, R14 ; 退出到调用者并恢复标志位(不遵从 32-bit体系)

(7)MVN指令:传送取反的值

格式:MVN{条件}{s} 目的寄存器, 源操作数

MVN     R0, #4                  ; R0 = -5
MVN R0, #0 ; R0 = -1

(8)ORR指令:逻辑或

格式:ORR{条件}{S} 目的寄存器 操作数1 操作数2

ORR     R0, R0, #              ; 设置 R0 中位 0 和 1

(9)RSB指令:反向减法

格式:RSB{条件}{S} 目的寄存器 操作数1 操作数2

RSB     R0, R1, R2              ; R0 = R2 - R1
RSB R0, R1, # ; R0 = 256 - R1
RSB R0, R2, R3,LSL# ; R0 = (R3 << 1) - R2

(10)RSC指令:带借位的反向减法

格式:RSC{条件}{S} 目的寄存器 操作数1 操作数2(目的寄存器 = 操作数2 - 操作数1 - !carry)

(11)SBC指令:带借位的减法

格式:SBC{条件}{S} 目的寄存器 操作数1 操作数2(目的寄存器 = 操作数1 - 操作数2 - !carry)

(12)SUB指令:减法

格式:SUB{条件}{S} 目的寄存器 操作数1 操作数2

SUB     R0, R1, R2              ; R0 = R1 - R2
SUB R0, R1, # ; R0 = R1 - 256
SUB R0, R2, R3,LSL# ; R0 = R2 - (R3 << 1)

4. 移位操作

(1)LSL指令:

(2)ASL指令:

(3)LSR指令:

(4)ASR指令:

(5)ROR指令:

(6)RRX指令:

5. 乘法指令

(1)MLA指令:

(2)MUL指令:

6. 比较指令

(1)CMN

(2)CMP

(3)TEQ

(4)TST

6. 分支指令:用于实现程序流程的跳转

(1)B指令:分支

格式: B {条件} 目标地址

(2)BL:带返回的跳转指令(在跳转之前将PC值保存在R14中)

格式: BL {条件} 目标地址

CMP R1, #
BEQ Label

(3)条件执行

BEQ   Branch if EQual
BNE Branch if Not Equal
BVS Branch if oVerflow Set
BVC Branch if oVerflow Clear
BHI Branch if HIgher
BLS Branch if Lower or the Same
BPL Branch if PLus
BMI Branch if MInus
BCS Branch if Carry Set
BCC Branch if Carry Clear
BGE Branch if Greater than or Equal
BGT Branch if Greater Than
BLE Branch if Less than or Equal
BLT Branch if Less Than

7. 软件中断指令

(1)SWI

格式:SWI{条件} <24 位编号>

①执行SWI软中断指令,硬件会做的事情:

* 进入Supervisor模式

* 拷贝CPSR至SPSR_svc

* 拷贝异常返回地址至LR_svc

* 将0x00000008装入PC

上一篇:shell Builtin variables(shell内建变量)


下一篇:运行shell文件时提示/bin/bash^M: bad interpreter: 没有那个文件