Presentation is loading. Please wait.

Presentation is loading. Please wait.

第3章 ARM寻址方式与指令系统 ARM编程模型 ARM指令格式和寻址方式 ARM指令集 Thumb指令集.

Similar presentations


Presentation on theme: "第3章 ARM寻址方式与指令系统 ARM编程模型 ARM指令格式和寻址方式 ARM指令集 Thumb指令集."— Presentation transcript:

1 第3章 ARM寻址方式与指令系统 ARM编程模型 ARM指令格式和寻址方式 ARM指令集 Thumb指令集

2 机器指令、伪指令和宏指令 机器指令:能被处理器直接执行,而伪指令宏和宏指令不能。机器指令包括ARM指令集和Thumb指令集 ;
伪指令:在源程序汇编期间,由汇编编译器处理。其作用是为汇编程序完成准备工作; 宏指令:在程序中用于调用宏,宏是一段独立的程序代码;在程序汇编时,对宏调用进行展开,用宏体代替宏指令。

3 ARM处理器模式 ARM微处理器支持7种工作模式:用户模式、系统模式、快速中断模式、外部中断模式、管理模式、中止模式、未定义指令模式。
除用户模式之外的其余6种称为非用户模式,或特权模式。 在特权模式中,除系统模式之外的其余5种称为异常模式。 处理器的各种工作模式由当前程序状态寄存器CPSR的低5位M[4:0]决定。 工作模式切换: (1)发生异常,处理器自动改变CPSR中M[4:0]的值,进入相应的工作模式; (2)处理器处于特权模式时,用指令向CPSR的M[4:0]字段写入特定的值,进入相应的工作模式。 用户模式时,不能改变工作模式,除非发生异常。

4 与用户模式类似,但具有可以直接切换到其它模式等特权
ARM处理器7种工作模式 处理器模式 说明 备注 M[4:0] 用户 (usr) 正常程序执行模式 不能直接切换到其它模式 10000 快速中断 (fiq) 支持高速数据传输及通道处理 FIQ异常响应时进入此模式 10001 外部中断 (irq) 用于通用中断处理 IRQ异常响应时进入此模式 10010 管理 (svc) 操作系统保护模式 系统复位和软件中断响应时进入此模式 10011 中止 (abt) 用于支持虚拟内存和/或存储器保护 在ARM7TDMI没有大用处 10111 未定义 (und) 支持硬件协处理器的软件仿真 未定义指令异常响应时进入此模式 11011 系统 (sys) 运行操作系统的特权任务 与用户模式类似,但具有可以直接切换到其它模式等特权 11111

5 处理器的工作状态 从编程的角度讲,ARM处理器工作在两种状态:ARM状态或Thumb状态。
(2)Thumb状态:处理器执行16位的thumb指令集时,工作在这种状态。 状态切换:通过跳转指令实现。

6 ARM的寄存器组织 37个寄存器:31个通用寄存器,包括程序计数器PC; 6个状态寄存器。
寄存器均为32位,分成7组,各工作模式拥有自己的寄存器组,只能访问自己的寄存器组。 有些寄存器是重叠的,有些是工作模式特有的。 在不同的工作模式和处理器状态下,程序员可以访问的寄存器不尽相同。 不分组8个 通用31个 2组10个 分组22个 6组12个 SP LR PC PC 1个 CPSR CPSR CPSR CPSR CPSR 状态6个 SPSR SPSR SPSR SPSR SPSR

7 Thumb寄存器在ARM寄存器上的映射 低寄存器 高寄存器
堆栈指针 (R13) 连接寄存器 (R14) 程序计数器 (R15) 低寄存器 在Thumb中,高寄存器不是标准寄存器。汇编语言程序员对它们的访问受到限制。可以使用MOV、CMP和ADD指令对高寄存器操作。 高寄存器

8 状态寄存器 条件代码标志 保留 控制位 N Z C V — I M0 M1 M2 M3 M4 T F . . . N Z C V Q I F
CPSR:当前程序状态寄存器,可以在任何工作模式下被访问。 SPSR:程序状态保存寄存器,只有在异常模式下,才能被访问;各异常模式拥有自己的SPSR。发生异常时,SPSR保存CPSR的值,格式同CPSR。 状态标志:5个,N符号位,Z零标志,C进位,V溢出位,Q DSP运算溢出位。 控制标志:4个,I中断允许,F快速中断允许,T状态选择,M[4:0] 处理器工作模式 条件代码标志 保留 控制位 N Z C V I M0 M1 M2 M3 M4 T F . . . N Z C V Q I F T M0 M1 M2 M3 M4 溢出标志 oVerflow 进位或借位扩展 Carry 模式位 Mode 状态位 Thumb 零 Zero FIQ禁止 Fast 负或小于 Negative IRQ禁止 Interrupt

9 条件标志位 标志位 含 义 N 当两个补码表示的带符号数运算时,N=1 表示运算的结果为负数;N=0 表示运算的结果为正数或零; Z
含 义 N 当两个补码表示的带符号数运算时,N=1 表示运算的结果为负数;N=0 表示运算的结果为正数或零; Z Z=1 表示运算的结果为零;Z=0表示运算的结果不为零; C 有3种情况会改变C的值: 加法运算(包括比较指令CMN):当运算结果产生了进位时(无符号数上溢出),C=1,否则C=0。 减法运算(包括比较指令CMP):当运算时产生了借位(无符号数下溢出),C=0,否则C=1。 对于包含移位操作的非加/减运算指令,C为移出值的最后一位。 V 对于加/减法运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出。 Q 在ARM v5及以上版本的E系列处理器中,用Q标志位指示增强的DSP运算指令是否发生了溢出。

10 I=1,表示禁止IRQ中断;否则,表示允许IRQ中断 F=1,表示禁止FIQ中断;否则,表示允许FIQ中断
控制位 标志位 含义 I I=1,表示禁止IRQ中断;否则,表示允许IRQ中断 F F=1,表示禁止FIQ中断;否则,表示允许FIQ中断 T 对于ARM v4以上版本的T系列处理器,T=0,表示执行ARM指令,否则,表示执行Thumb指令; 对于ARM v5以上版本的非T系列处理器,T=0,表示指令ARM指令,否则,表示强制下一条执行的指令产生未定义指令中断。 M[4:0] 处理器工作模式 可访问的寄存器 10000 用户模式 PC,R0~R14,CPSR 10001 快速中断模式 PC,R0~R7,R8_fiq~R14_fiq,CPSR,SPSR_fiq 10010 外部中断模式 PC,R0~R12,R13_irq~R14_irq,CPSR,SPSR_irq 10011 管理模式 PC,R0~R12,R13_svc~R14_svc,CPSR,SPSR_svc 10111 中止模式 PC,R0~R12,R13_abt~R14_abt,CPSR,SPSR_abt 11011 未定义指令模式 PC,R0~R12,R13_und~R14_und,CPSR,SPSR_und 11111 系统模式

11 异常中断 异常中断:处理器由于外部或内部的原因,停止执行当前任务,转而处理特定的事件,处理完后返回原程序,继续执行。
当异常发生时,处理器首先自动保存当前状态,即返回地址存入寄存器R14,当前寄存器CPSR存入SPSR中,接着进入相应的工作模式,并执行特定地址的指令。 ARM共有7种类型的异常,不同类型的异常将导致处理器进入不同的工作模式,并执行不同特定地址的指令。

12 7种类型异常中断 复位:复位异常时,处理器立即停止当前程序,进入禁止中断的管理模式,并从地址0x00000000处开始执行。
未定义指令:当前指令未定义时,便产生未定义指令中断。 软件中断:用户模式下使用指令SWI时,处理器便产生软件中断,进入管理模式,以调用特权操作。 指令预取中止:预取指令的地址不存在,或不允许当前指令访问时,存储器会向处理器发出中止信号;预取指令被执行时才会产生该类异常。 数据访问中止:数据访问指令的地址不存在,或不允许当前指令访问时,产生数据中止异常。 外部中断请求:外部中断请求引脚有效,且CPSR中的I位为0时,产生IRQ异常。 快速中断请求:快速中断请求引脚有效,且CPSR中的F位为0时,产生FIQ异常。

13 异常向量 地址 异常类型 进入时的模式 进入时I的状态 进入时F的状态 0x0000 0000 复位 管理 禁止 0x0000 0004
未定义指令 未定义 I F 0x 软件中断(SWI) 0x C 预取中止(指令) 中止 0x 数据中止 0x 保留 0x IRQ 外部中断 0x C FIQ 快速中断

14 异常中断的优先级 异常类型 优先级 复位 1(最高优先级) 数据中止 2 FIQ 3 IRQ 4 预取中止 5 未定义指令 6 SWI
6(最低优先级) 优先级降低

15 复位 当nRESET信号由低变为高电平时,ARM处理器执行下列操作: 1. 强制CPSR中的M[4:0]变为b10011(管理模式);
2. 置位CPSR中的I和F位; 3. 清零CPSR中的T位; 4. 强制PC从地址0x00开始对下一条指令进行取指; 5. 返回到ARM状态并恢复执行 。

16 bootloader源代码外部中断处理实例
从0x 开始设置以下指令。 发生外部中断请求,处理器自动保存当前状态(PC→R14,CPSR→SPSR),进入外部中断模式,执行地址0x 处的指令。 b SYS_RST_HANDLER ;0x b UDF_INS_HANDLER ;0x b SWI_SVC_HANDLER ;0x b INS_ABT_HANDLER ;0x c b DAT_ABT_HANDLER ;0x b ; b IRQ_SVC_HANDLER ;0x b FIQ_SVC_HANDLER ;0x c ROM空间

17 bootloader源代码外部中断处理实例
在IRQ_SVC_HANDLER中,处理器将通用寄存器和返回地址压入堆栈,接着跳转到外部中断请求的中断服务程序中。 IRQ_SVC_Vector为外部中断请求的中断向量。 IRQ_SVC_HANDLER处的代码为: IRQ_SVC_HANDLER sub lr, lr, #4 stmfd sp!, {r0-r3, lr} ldr r0, =IRQ_SVC_Vector ldr pc, [r0]

18 bootloader源代码外部中断处理实例
中断向量地址分配 (内存表数据结构说明): MAP _ISR_STARTADDRESS ;为中断向量分配地址空间 SYS_RST_VECTOR # 4 ;此空间处为RAM的地址 UDF_INS_VECTOR # 4 SWI_SVC_VECTOR # 4 INS_ABT_VECTOR # 4 DAT_ABT_VECTOR # 4 RESERVED_VECTOR # 4 IRQ_SVC_VECTOR # 4 FIQ_SVC_VECTOR # 4 中断向量设置程序: ldr r0, IRQ_SVC_VECTOR ;IsrIRQ为中断服务程序的入口地址 ldr r1,=IsrIRQ ;将其写入中断向量IRQ_SVC_VECTOR中 str r1,[r0]

19 bootloader源代码外部中断处理实例
在7种异常中断中,外部中断请求较特殊,它包括26种中断。在非向量IRQ中断模式下,这些中断的中断服务程序可通过IRQ的中断服务程序间接进入 。 IRQ中断服务程序代码如下: IsrIRQ sub sp,sp,#4 stmfd sp!,{r8-r9} ldr r9,=I_ISPR ldr r9,[r9] ;读出中断寄存器I_ISPR的值,存入R9中 mov r8,#0x0 movs r9,r9,lsr #1 bcs %F1 add r8,r8,#4 ;根据I_ISPR的值 b %B0 ;判断该中断在普通中断向量表中的偏移量,存入R8 1 ldr r9,=HandleADC ;HandleADC为普通中断向量表的起始地址, add r9,r9,r8 ;起始地址+偏移地址=实际的中断向量地址 ldr r9,[r9] ;取出中断向量的值,即服务程序的地址 str r9,[sp,#8] ldmfd sp!,{r8-r9,pc} ;跳转到普通中断服务程序,开始执行

20 bootloader源代码外部中断处理实例
外部中断包括的26种普通中断的向量空间分配 HandleADC # 4 ;为普通中断向量分配空间 HandleRTC # 4 HandleUTXD1 # 4 HandleUTXD0 # HandleEINT3 # 4 HandleEINT2 # 4 HandleEINT1 # 4 HandleEINT0 # 4 ;

21 ARM指令的编码格式 实际指令语法格式为: ADDEQS R0,R1,R2; 该指令的编码格式为: 31~28 27~25 24~21 20
19~16 15~12 11~~~~~~~~~~0 cond opcode S Rn Rd op2 0000 001 0100 1 0001

22 ARM指令的助记符 ARM指令在汇编程序中用助记符表示,一般ARM指令的助记符格式为:
<opcode>{<cond>} {S} <Rd>,<Rn>,<op2> 其中: <opcode> 操作码,如ADD表示算术加操作指令; {<cond>} 决定指令执行的条件域; {S} 决定指令执行是否影响CPSR寄存器的值; <Rd> 目的寄存器; <Rn> 第一个操作数,为寄存器; <op2> 第二个操作数。 例如,指令 ADDEQS R1,R2,#5

23 条件域<cond> 几乎所有的ARM指令都可以根据当前程序状态寄存器CPSR中标志位的值,有条件地执行。
ARM指令的条件域<cond>有16种类型。 cond CPSR中标志位 含 义 EQ Z置位 相等 NE Z清零 不相等 CS C置位 无符号数大于或等于 CC C清零 无符号数小于 MI N置位 负数 PL N清零 正数或零 VS V置位 溢出 VC V清零 未溢出 HI C置位Z清零 无符号数大于 LS C清零Z置位 无符号数小于或等于 GE N等于V 带符号数大于或等于 LT N不等于V 带符号数小于 GT Z清零且(N等于V) 带符号数大于 LE Z置位或(N不等于V) 带符号数小于或等于 AL 忽略 无条件执行 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 依版本不同,定义不同

24 寻址方式 9种: 立即数寻址 寄存器寻址 寄存器移位寻址 寄存器间接寻址 基址变址寻址 相对寻址 多寄存器寻址 块拷贝寻址 堆栈寻址

25 立即数寻址 在立即数寻址中,操作数本身直接在指令中给出,取出指令也就获得了操作数,这个操作数也称为立即数。 例:
ADD R0,R1,#5; R0=R1+5 MOV R0,#0x55; R0=0x55 其中:操作数5,0x55就是立即数,立即数在指令中要以“#”为前缀,后面跟实际数值。

26 寄存器寻址 在寄存器寻址方式下,寄存器的值即为操作数。ARM指令普遍采用此种寻址方式。 例: ADD R0,R1,R2 ; R0=R1+R2
MOV R0,R1 ; R0=R1

27 寄存器移位寻址 寄存器移位寻址的操作数由寄存器的数值做相应移位而得到。
移位的方式在指令中以助记符的形式给出,而移位的位数可用立即数或寄存器寻址方式表示。 例: ADD R0,R1,R2,ROR #5 ;R0=R1+R2循环右移5位 MOV R0,R1,LSL R3 ;R0=R1逻辑左移R3位 移位操作在ARM指令集中不作为单独的指令使用,ARM指令集共有5种位移操作。

28 ARM指令集的5种位移操作 LSL逻辑左移 :Rx,LSL <op1> LSR逻辑右移 : Rx,LSR <op1>
ASR算术右移 :Rx,ASR <op1> ROR循环右移 :Rx,ROR <op1> RRX带扩展的循环右移:Rx,RRX

29 寄存器间接寻址 寄存器中的值为操作数的物理地址,而实际的操作数存放在存储器中。 例: STR R0,[R1] ; [R1]=R0
LDR R0,[R1] ; R0=[R1]

30 基址变址寻址 将寄存器(称为基址寄存器)的值与指令中给出的偏移地址量相加,所得结果作为操作数的物理地址。 例:
LDR R0,[R1,#5] ; R0=[R1+5] LDR R0,[R1,R2] ; R0=[R1+R2]

31 相对寻址 相对寻址同基址变址寻址相似,区别只是将程序计数器PC作为基址寄存器,指令中的标记作为地址偏移量。 例: BEQ process1
…… process1

32 多寄存器寻址 在多寄存器寻址方式中,一条指令可实现一组寄存器值的传送。 连续的寄存器间用“-”连接,否则用“,”分隔。 例:
LDMIA R0,{R1-R5} ;R1=[R0],R2=[R0+4],R3=[R0+8] ;R4=[R0+12],R5=[R0+16] 指令中IA表示在执行完一次Load操作后,R0自增4。该指令将以R0为起始地址的5个字数据分别装入R1,R2,R3,R4,R5中。

33 块拷贝寻址 块拷贝寻址可实现连续地址数据从存储器的某一位置拷贝到另一位置。 例: LDMIA R0,{R1-R5};
STMIA R1,{R1-R5}; 第一条指令从以R0的值为起始地址的存储单元中取出5个字的数据,第二条指令将取出的数据存入以R1的值为起始地址的存储单元中。 实际上是多寄存器寻址的组合。

34 堆栈寻址 堆栈寻址用于数据栈与寄存器组之间批量数据传输。 当数据写入和读出内存的顺序不同时,使用堆栈寻址可以很好的解决这问题。 例:
STMFD R13!,{R0,R1,R2,R3,R4}; LDMFD R13!,{R0,R1,R2,R3,R4} 第一条指令,将R0-R4中的数据压入堆栈,R13为堆栈指针; 第二条指令,将数据出栈,恢复R0-R4原先的值。

35 ARM指令集 6种类型(53种主要助记符) : 数据处理指令(22种主要助记符) 跳转指令(4种主要助记符)
Load/Store指令(16种主要助记符) 程序状态寄存器指令(2种主要助记符) 协处理器指令(5种主要助记符) 软件中断指令 (2种主要助记符)

36 数据处理指令1 1.MOV 数据传送指令 格式:MOV{<cond>}{S} <Rd>,<op1>;
例如: MOV R0,#5 ;R0=5 MOV R0,R1 ;R0=R1 MOV R0,R1,LSL#5 ;R0=R1左移5位

37 数据处理指令2 2.MVN 数据取反传送指令 格式:MVN{<cond>}{S} <Rd>,<op1>;
功能:将op1表示的值传送到目的寄存器Rd中,但该值在传送前被按位取反,即Rd=!op1; op1可以是寄存器、被移位的寄存器或立即数。 例如: MVN R0,#0 ;R0=-1

38 数据处理指令3 3.ADD 加法指令 格式:ADD{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn+op2 op2可以是寄存器,被移位的寄存器或立即数。 例如: ADD R0,R1,#5 ;R0=R1+5 ADD R0,R1,R2 ;R0=R1+R2 ADD R0,R1,R2,LSL#5 ;R0=R1+R2左移5位

39 数据处理指令4 4.ADC 带进位加法指令 格式:ADC{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn+op2+carry op2可以是寄存器、被移位的寄存器或立即数;carry为进位标志值。该指令用于实现超过32位的数的加法。 例如: 第一个64位操作数存放在寄存器R2,R3中; 第二个64位操作数存放在寄存器R4,R5中; 64位结果存放在R0,R1中。 64位的加法可由以下语句实现: ADDS R0,R2,R4 ;低32位相加,S表示结果影响条件标志位的值 ADC R1,R3,R5 ;高32位相加

40 数据处理指令5 5.SUB 减法指令 格式:SUB{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn-op2 op2可以是寄存器、被移位的寄存器或立即数。 例如: SUB R0,R1,#5 ;R0=R1-5 SUB R0,R1,R2 ;R0=R1-R2 SUB R0,R1,R2,LSL#5 ;R0=R1-R2左移5位

41 数据处理指令6 6.RSB 反向减法指令 格式:RSB{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:同SUB指令,但倒换了两操作数的前后位置,即Rd=op2-Rn。 例如: RSB R0,R1,#5 ;R0=5-R1 RSB R0,R1,R2 ;R0=R2-R1 RSB R0,R1,R2,LSL#5 ;R0=R2左移5位-R1

42 数据处理指令7 7.SBC 带借位减法指令 格式:SBC{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn-op2-!carry op2可以是寄存器、被移位的寄存器或立即数。 SUB和SBC生成进位标志的方式不同于常规,如果需要借位则清除进位标志,所以指令要对进位标志进行一个非操作。 例如: 第一个64位操作数存放在寄存器R2,R3中; 第二个64位操作数存放在寄存器R4,R5中; 64位结果存放在R0,R1中。 64位的减法(第一个操作数减去第二个操作数)可由以下语句实现: SUBS R0,R2,R4; 低32位相减,S表示结果影响条件标志位的值 SBC R1,R3,R5; 高32位相减

43 数据处理指令8 8.RSC 带借位的反向减法指令
格式:RSC{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:同SBC指令,但倒换了两操作数的前后位置,即Rd=op2-Rn-!carry。 例如: 前提条件与SBC例子相同,操作数1-操作数2的实现语句需改为: SUBS R0,R2,R4; 低32位相减,S表示结果影响寄存器CPSR的值 RSC R1,R5,R3; 高32位相减

44 数据处理指令9 9.MUL 32位乘法指令 格式:MUL{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn×op2 该指令根据S标志,决定操作是否影响CPSR的值;其中op2必须为寄存器。Rn和op2的值为32位的有符号数或无符号数。 例如: MULS R0,R1,R2 ;R0=R1×R2,结果影响寄存器CPSR的值

45 数据处理指令10 10.MLA 32位乘加指令 格式:MLA{<cond>}{S} <Rd>,<Rn>,<op2>,<op3>; 功能:Rd=Rn×op2+op3 op2和op3必须为寄存器。Rn、op2和op3的值为32位的有符号数或无符号数。 例如: MLA R0,R1,R2,R3 ;R0=R1×R2+R3

46 数据处理指令11 11.SMULL 64位有符号数乘法指令 格式:
SMULL{<cond>}{S} <Rdl>,<Rdh>,<Rn>,<op2>; 功能:Rdh Rdl=Rn×op2 Rdh、Rdl和op2均为寄存器。Rn和op2的值为32位的有符号数。 例如: SMULL R0,R1,R2,R3 ;R0=R2×R3的低32位 ;R1=R2×R3的高32位

47 数据处理指令12 12.SMLAL 64位有符号数乘加指令 格式:
SMLAL{<cond>}{S} <Rdl>,<Rdh>,<Rn>,<op2>; 功能:Rdh Rdl=Rn×op2+Rdh Rdl Rdh、Rdl和op2均为寄存器。Rn和op2的值为32位的有符号数,Rdh Rdl的值为64位的加数。 例如: SMLAL R0,R1,R2,R3 ;R0=R2×R3的低32位+R0 ;R1=R2×R3的高32位+R1

48 数据处理指令13 13.UMULL 64位无符号数乘法指令 格式:
UMULL{<cond>}{S} <Rdl>,<Rdh>,<Rn>,<op2>; 功能:同SMULL指令,但指令中Rn和op2的值为32位的无符号数。 例如: UMULL R0,R1,R2,R3 ;R0=R2×R3的低32位 ;R1=R2×R3的高32位 其中R2,R3的值为无符号数

49 数据处理指令14 14.UMLAL 64位无符号数乘加指令 格式:
UMLAL {<cond>}{S} <Rdl>,<Rdh>,<Rn>,<op2>; 功能:同SMLAL指令,但指令中Rn,op2的值为32位的无符号数,Rdh Rdl的值为64位无符号数。 例如: UMLAL R0,R1,R2,R3 ;R0=R2×R3的低32位+R0 ;R1=R2×R3的高32位+R1 其中R2,R3的值为32位无符号数 R1,R0的值为64位无符号数

50 数据处理指令15 15.AND 逻辑与指令 格式:AND{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn AND op2 op2可以是寄存器,被移位的寄存器或立即数。一般用于清除Rn的特定几位。 例如: AND R0,R0,#5 ;保持R0的第0位和第2位,其余位清0

51 数据处理指令16 16.ORR 逻辑或指令 格式:ORR{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn OR op2 op2可以是寄存器、被移位的寄存器或立即数。一般用于设置Rn的特定几位。 例如: ORR R0,R0,#5 ;R0的第0位和第2位设置为1,其余位不变

52 数据处理指令17 17.EOR 逻辑异或指令 格式:EOR{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn EOR op2 op2可以是寄存器、被移位的寄存器或立即数。一般用于将Rn的特定几位取反。 例如: EOR R0,R0,#5 ;R0的第0位和第2位取反,其余位不变

53 数据处理指令18 18.BIC 位清除指令 格式:BIC{<cond>}{S} <Rd>,<Rn>,<op2>; 功能:Rd=Rn AND (!op2) 用于清除寄存器Rn中的某些位,并把结果存放到目的寄存器Rd中. 操作数op2是一个32位掩码(mask),如果在掩码中设置了某一位,则清除Rn中的这一位;未设置的掩码位指示Rn中此位保持不变。其中,op2可以是寄存器、被移位的寄存器或立即数。 例如: BIC R0,R0,#5 ;R0中第0位和第2位清0,其余位不变

54 数据处理指令19 19.CMP 比较指令 格式:CMP{<cond>} <Rn>,<op1>;
该指令进行一次减法运算,但不存储结果,根据结果更新CPSR中条件标志位的值。 该指令不需要显式地指定S后缀来更改状态标志。其中,操作数op1为寄存器或立即数。 例如: CMP R0,#5 ;计算R0-5,根据结果设置条件标志位 ADDGT R0,R0,#5 ;如果R0>5,则执行ADDGT指令

55 数据处理指令20 20.CMN 反值比较指令 格式:CMN{<cond>} <Rn>,<op1>;
功能:同CMP指令,但寄存器Rn的值是和op1取负的值进行比较。 例如: CMN R0,#5 ;把R0与-5进行比较

56 数据处理指令21 21.TST 位测试指令 格式:TST{<cond>} <Rn>,<op1>;
功能: Rn AND op1 根据结果更新CPSR中条件标志位的值,但不存储结果。 用于检查寄存器Rn是否设置了op1中相应的位。 例如: TST R0,#5 ;测试R0中第0位和第2位是否为1

57 数据处理指令22 22.TEQ 相等测试指令 格式:TEQ{<cond>} <Rn>,<op1>;
功能: Rn EOR op1 将寄存器Rn的值和操作数op1所表示的值按位作逻辑异或操作,根据结果更新CPSR中条件标志位的值,但不存储结果。 用于检查寄存器Rn的值是否和op1所表示的值相等。 例如: TEQ R0,#5 ;判断R0的值是否和5相等

58 跳转指令 跳转指令用于实现程序的跳转和程序状态的切换。 ARM程序设计中,实现程序跳转有两种方式: (1)跳转指令,
(2)直接向程序寄存器PC(R15)中写入目标地址值。 通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转。 使用跳转指令,其跳转空间受到限制。

59 跳转指令1 1.B 跳转指令 格式:B{<cond>} <addr>; 功能: PC= PC+ addr左移两位
addr的值是相对当前PC(即寄存器R15)的值的一个偏移量,而不是一个绝对地址,它是24位有符号数。实际地址的值由汇编器来计算. addr的值有符号扩展为32位后,左移两位,然后与PC值相加,即得到跳转的目的地址。 跳转的范围为-32MB~+32MB。 例如: B exit; 程序跳转到标号exit处 exit…

60 跳转指令2 2.BL 带返回的跳转指令 格式:BL{<cond>} <addr>;
功能:同B指令,但BL指令执行跳转操作的同时,还将PC(寄存器R15)的值保存到LR寄存器(寄存器R14)中。 该指令用于实现子程序调用,程序的返回可通过把LR寄存器的值复制到PC寄存器中来实现。 例如: BL func; 调用子程序func func MOV R15,R14; 子程序返回

61 跳转指令3 3.BLX 带返回和状态切换的跳转指令 格式:BLX <addr>;或BLX <Rn>;
功能:处理器跳转到目标地址处,并将PC(寄存器R15)的值保存到LR寄存器(R14)中。 如果目标地址处为Thumb指令,则程序状态从ARM状态切换为Thumb状态。 该指令用于子程序调用和程序状态的切换。 例如: BLX T16; 跳转到标号T16处执行,T16后面的指令为Thumb指令 CODE16 T16 后面指令为Thumb指令

62 跳转指令4 4.BX 带状态切换的跳转指令 格式:BX <Rn>; 功能:处理器跳转到目标地址处,从那里继续执行;
目标地址为寄存器Rn的值和0xFFFFFFFE作与操作的结果。 目标地址处的指令可以是ARM指令,也可以是Thumb 指令。 例如: ADR R0,exit ;标号exit处的地址装入R0中 BX R0 ;跳转到exit处

63 Load/Store指令 Load/Store指令用于寄存器和内存间数据的传送。 Load用于把内存中的数据装载到寄存器中。
该集合的指令使用频繁,在指令集中最为重要,因为其他指令只能操作寄存器,当数据存放在内存中时,必须先把数据从内存装载到寄存器,执行完后再把寄存器中的数据存储到内存中。 Load/Store指令分为3类: (1)单一数据传送指令(LDR和STR等) (2)多数据传送指令(LDM和STM) (3)数据交换指令(SWP和SWPB)

64 Load/Store指令1-1 1.LDR 字数据加载指令
格式:LDR{<cond>} <Rd>,<addr>; 功能:把addr所表示的内存地址中的字数据装载到目标寄存器Rd中,同时还可以把合成的有效地址写回到基址寄存器。 地址addr可以是一个简单的值、一个偏移量,或者是一个被移位的偏移量。 寻址方式: Rn:基址寄存器。 Rm:变址寄存器。 Index:偏移量,12位的无符号数。 LDR Rd,[Rn] ;把内存中地址为Rn的字数据装入寄存器Rd中 LDR Rd,[Rn,Rm] ;将内存中地址为Rn+Rm的字数据装入寄存器Rd中

65 Load/Store指令1-2 LDR Rd,[Rn,#index] ;将内存中地址为Rn+index的字数据装入Rd中
LDR Rd,[Rn,Rm,LSL#5] ;将内存中地址为Rn+Rm×32的字数据装入Rd LDR Rd,[Rn,Rm] ! ;将内存中地址为Rn+Rm的字数据装入Rd,并将新地址Rn+Rm写入Rn LDR Rd,[Rn,#index] ! ;将内存中地址为Rn+index的字数据装入Rd,并将新地址Rn+index写入Rn LDR Rd,[Rn,Rm,LSL#5]! ;将内存中地址为Rn+Rm×32的字数据装入Rd,并将新地址Rn+Rm×32写入Rn

66 Load/Store指令1-3 LDR Rd,[Rn],Rm ;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+Rm写入Rn
LDR Rd,[Rn],#index ;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+index写入Rn LDR Rd,[Rn],Rm,LSL#5 ;将内存中地址为Rn的字数据装入寄存器Rd,并将新地址Rn+Rm×32写入Rn 例如: LDR R0,[R1,R2,LSL#5]! ; 将内存中地址为R1+R2×32的字数据装入寄存器R0,并将新地址R1+R2×32写入R1

67 Load/Store指令1-4 LDR {<cond>}<Rd>, <addressing_mode>
指令操作的伪代码: if ConditionPassed(cond) then if adderss[1:0] = = 0b00 then Value = Memory[adderss,4] else if adderss[1:0] = = 0b01 then Value = Memory[adderss,4] Rotate_Right 8 else if adderss[1:0] = = 0b10 then Value = Memory[adderss,4] Rotate_Right 16 else if adderss[1:0] = = 0b11 then Value = Memory[adderss,4] Rotate_Right 24 if (Rd is R15) then if (architecture version 5 or above) then PC = value AND 0xFFFFFFFE T Bit = value[0] else PC = value AND 0xFFFFFFFC Rd = value

68 Load/Store指令2 2.LDRB 字节数据加载指令
格式:LDR{<cond>}B <Rd>,<addr>; 功能:同LDR指令,但该指令只是从内存读取一个8位的字节数据而不是一个32位的字数据,并将Rd的高24位清0。 例如: LDRB R0,[R1] ;将内存中起始地址为R1的一个字节数据装入R0中

69 Load/Store指令3 3.LDRBT 用户模式的字节数据加载指令
格式:LDR{<cond>}BT <Rd>,<addr>; 功能:同LDRB指令,但无论处理器处于何种模式,都将该指令当作一般用户模式下的内存操作。

70 Load/Store指令4 4.LDRH 半字数据加载指令
格式:LDR{<cond>}H <Rd>,<addr>; 功能:同LDR指令,但该指令只是从内存读取一个16位的半字数据而不是一个32位的字数据,并将Rd的高16位清0。 例如: LDRH R0,[R1] ;将内存中起始地址为R1的一个半字数据装入R0中

71 Load/Store指令5 5.LDRSB 有符号的字节数据加载指令
格式:LDR{<cond>}SB <Rd>,<addr>; 功能:同LDRB指令,但该指令将寄存器Rd的高24位设置成所装载的字节数据符号位的值。 例如: LDRSB R0,[R1] ;将内存中起始地址为R1的一个字节数据装入R0中,R0的高24位设置成该字节数据的符号位

72 Load/Store指令6 6.LDRSH 有符号的半字数据加载指令
格式:LDR{<cond>}SH <Rd>,<addr>; 功能:同LDRH指令,但该指令将寄存器Rd的高16位设置成所装载的半字数据符号位的值。 例如: LDRSH R0,[R1] ;将内存中起始地址为R1的一个16位半字数据装入R0中,R0的高16位设置成该半字数据的符号位

73 Load/Store指令7 7.LDRT 用户模式的字数据加载指令
格式:LDR{<cond>}T <Rd>,<addr>; 功能:同LDR指令,但无论处理器处于何种模式,都将该指令当作一般用户模式下的内存操作。 addr所表示的有效地址必须是字对齐的,否则从内存中读出的数值需进行循环右移操作。

74 Load/Store指令8 8.STR 字数据存储指令
格式:STR{<cond>} <Rd>,<addr>; 功能:把寄存器Rd中的字数据(32位)保存到addr所表示的内存地址中,同时还可以把合成的有效地址写回到基址寄存器。 地址addr可以是一个简单的值、一个偏移量,或者是一个被移位的偏移量。 寻址方式同LDR指令。 例如: STR R0,[R1,#5]! ;把R0中的字数据保存到以R1+5为地址的内存中,然后R1=R1+5

75 Load/Store指令9 9.STRB 字节数据存储指令
格式:STR{<cond>}B <Rd>,<addr>; 功能:把寄存器Rd中的低8位字节数据保存到addr所表示的内存地址中。 其他用法同STR指令。 例如: STRB R0,[R1] ;将寄存器R0中的低8位数据存入R1表示的内存地址中

76 Load/Store指令10 10.STRBT 用户模式的字节数据存储指令
格式:STR{<cond>}BT <Rd>,<addr>; 功能:同STRB指令,但无论处理器处于何种模式,该指令都将被当作一般用户模式下的内存操作。

77 Load/Store指令11 11.STRH 半字数据存储指令
格式:STR{<cond>}H <Rd>,<addr>; 功能:把寄存器Rd中的低16位半字数据保存到addr所表示的内存地址中,而且addr所表示的地址必须是半字对齐的。 其他用法同STR指令。 例如: STRH R0,[R1] ;将寄存器R0中的低16位数据存入R1表示的内存地址中

78 Load/Store指令12 12.STRT 用户模式的字数据存储指令
格式:STR{<cond>}T <Rd>,<addr>; 功能:同STR指令,但无论处理器处于何种模式,该指令都将被当作一般用户模式下的内存操作。

79 Load/Store指令13-1 13.LDM 批量数据加载指令 格式:
LDM{<cond>}{<type>} <Rn>{!},<regs>{^}; 功能:从一片连续的内存单元读取数据到各个寄存器中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。 该指令一般用于多个寄存器数据的出栈。 type字段种类: IA:每次传送后地址加1。 IB:每次传送前地址加1。 DA:每次传送后地址减1。 DB:每次传送前地址减1。 FD:满递减堆栈。 ED:空递减堆栈。 FA:满递增堆栈。 EA:空递增堆栈。

80 Load/Store指令13-2 例如 LDMIA/IB/DA/DB R13!,{R0-R1,R3}; 各指令执行完后,结果如图所示。

81 Load/Store指令13-3 FD、ED、FA和EA指定是满栈还是空栈,是升序栈还是降序栈,用于堆栈寻址。
一个满栈的栈指针指向上次写的最后一个数据单元. 空栈的栈指针指向第一个空闲单元。 一个降序栈是在内存中反向增长而升序栈在内存中正向增长。

82 Load/Store指令13-4 格式: LDM{<cond>}{<type>} <Rn>{!},<regs>{^}; {!}:若选用了此后缀,则当指令执行完毕后,将最后的地址写入基址寄存器。 {^}:当regs中不包含PC时,该后缀用于指示指令所用的寄存器为用户模式下的寄存器,否则指示指令执行时,将寄存器SPSR的值复制到CPSR中。

83 Load/Store指令13-5 LDM {<cond>}<addressing_mode> <Rd>{!}, <registers> 指令操作的伪代码: if ConditionPassed(cond) then adderss = start_address for i = 0 to 14 if registers _list[i] = = 1 then Ri = Memory[adderss,4] adderss = address + 4 if registers _list[15] = = 1 then value = Memory[adderss,4] if (architecture version 5 or above) then PC = value AND 0xFFFFFFFE T Bit = value[0] else PC = value AND 0xFFFFFFFC assert end_adderss = address - 4

84 Load/Store指令13-6 指令操作的伪代码: if ConditionPassed(cond) then
LDM {<cond>}<addressing_mode> <Rd>{!}, <registers_and_pc>^ 指令操作的伪代码: if ConditionPassed(cond) then adderss = start_address for i = 0 to 14 if registers _list[i] = = 1 then Ri = Memory[adderss,4] adderss = address + 4 CPSR = SPSR value = Memory[adderss,4] if (architecture version 4T, 5 or above) and (T Bit = = 1) then PC = value AND 0xFFFFFFFE else PC = value AND 0xFFFFFFFC assert end_adderss = address - 4

85 Load/Store指令14-1 14.STM 批量数据存储指令
格式:STM{<cond>}{<type>} <Rn>{!},<regs>{^}; 功能:将各个寄存器的值存入一片连续的内存单元中,内存单元的起始地址为基址寄存器Rn的值,各个寄存器由寄存器列表regs表示。 该指令一般用于多个寄存器数据的入栈。 {^}:指示指令所用的寄存器为用户模式下的寄存器。 其他参数用法同LDM指令。 例如: STMEA R13!,{R0-R12,PC} ;将寄存器R0~R12以及程序计数器PC的值保存到R13指示的堆栈中

86 Load/Store指令14-2 指令操作的伪代码: if ConditionPassed(cond) then
STM {<cond>}<addressing_mode> <Rn>{!}, <registers> 指令操作的伪代码: if ConditionPassed(cond) then adderss = start_address for i = 0 to 15 if registers _list[i] = = 1 then Memory[adderss,4] = Ri adderss = address + 4 assert end_adderss = address - 4

87 Load/Store指令15 15.SWP 字数据交换指令
格式:SWP{<cond>} <Rd>,<op1>,[<op2>]; 功能: Rd=[op2],[op2]=op1 从op2所表示的内存装载一个字并把这个字放置到目的寄存器Rd中,然后把寄存器op1的内容存储到同一内存地址中。 op1,op2均为寄存器。 例如: SWP R0,R1,[R2] ;将R2所表示的内存单元中的字数据装载到R0,然后将R1中的字数据保存到R2所表示的内存单元中

88 Load/Store指令16 16.SWPB 字节数据交换指令
格式:SWP{<cond>}B <Rd>,<op1>,[<op2>]; 功能:从op2所表示的内存装载一个字节并把这个字节放置到目的寄存器Rd的低8位中,Rd的高24位设置为0;然后将寄存器op1的低8位数据存储到同一内存地址中。 例如: SWPB R0,R1,[R2] ;将R2所表示的内存单元中的一个字节数据装载到R0的低8位,然后将R1中的低8位字节数据保存到R2所表示的内存单元中

89 程序状态寄存器指令 用于状态寄存器和通用寄存器间传送数据。 总共有两条指令:MRS和MSR。 两者结合可用来修改程序状态寄存器的值。

90 程序状态寄存器指令1 1.MRS 程序状态寄存器到通用寄存器的数据传送指令
格式:MRS{<cond>} <Rd>,CPSR/SPSR; 功能:用于将程序状态寄存器的内容传送到目标寄存器Rd中。 当进入中断服务程序或进程切换时,该指令可用来保存当前状态寄存器的值。 例如: MRS R0,CPSR ;状态寄存器CPSR的值存入寄存器R0中

91 程序状态寄存器指令2 2.MSR 通用寄存器到程序状态寄存器的数据传送指令
格式:MSR{<cond>} CPSR/SPSR_<field>,<op1>; 功能:用于将寄存器Rd的值传送到程序状态寄存器中。 当退出中断服务程序或进程切换时,该指令可用来恢复状态寄存器的值。 操作数op1可以是通用寄存器或立即数。 <field>:用来设置状态寄存器中需要操作的位。 32位的状态寄存器可以分为4个域: 位[31:24]为条件标志位域,用f表示。 位[23:16]为状态位域,用s表示。 位[15:8]为扩展位域,用x表示。 位[7:0]为控制位域,用c表示。 例如:MSR CPSR_f,R0 ;用R0的值修改CPSR的条件标志域 MSR CPSR_fsxc,#5; CPSR的值修改为5

92 协处理器指令 ARM处理器最多可支持16个协处理器,用于辅助ARM完成各种协处理操作。
(1)ARM处理器用于初始化协处理器的数据操作指令(CDP)。 (2)协处理器寄存器和内存单元之间的数据传送指令(LDC,STC)。 (3)ARM处理器寄存器和协处理器寄存器之间的数据传送指令(MCR,MRC)。

93 异常中断指令1 1.SWI 软件中断指令 格式:SWI {<cond>} 24位的立即数;
功能:用于产生软件中断,以使用户程序调用操作系统的系统例程。 指令中24位的立即数指定用户程序调用系统例程的类型,其参数通过通用寄存器传递。 当24位的立即数被忽略时,系统例程类型由寄存器R0指定,其参数通过其他通用寄存器传递。 例如: SWI 0X05; 调用编号为05的系统例程。

94 异常中断指令2 SWI {<cond>}<immed_24> 指令操作的伪代码:
if ConditionPassed(cond) then R14_svc = adderss of next instruction after the SWI instruction SPSR_svc = CPSR CPSR[4:0] = 0b10011 /* Enter Supervisor mode */ CPSR[5] = 0 /* Execute in ARM state, T Bit = 0*/ /* CPSR[6] is unchanged, fiq不变*/ CPSR[7] = 1 /* Disable normal interrupt,I Bit = 1, 禁止irq */ if high vectors configured then PC = 0xFFFF0008 else PC = 0x

95 异常中断指令3 2.BKPT 断点中断指令 格式:BKPT 16位的立即数;
功能:用于产生软件断点中断,以便软件调试时使用。16位的立即数用于保存软件调试中额外的断点信息。 指令操作的伪代码: if (not overdiden by debug hardware) then R14_abt = adderss of BKPT instruction + 4 SPSR_abt = CPSR CPSR[4:0] = 0b10111 /* 中止模式 */ CPSR[5] = 0 /* 使程序处于 ARM 状态, T Bit = 0*/ /* CPSR[6] is unchanged, fiq不变*/ CPSR[7] = 1 /* 禁止正常中断,I Bit = 1, 禁止irq */ if high vectors configured then PC = 0xFFFF000C else PC = 0x C

96 Thumb指令集 Thumb指令集可以看做ARM指令集的一个子集,用于支持存储系统数据总线为16位的应用系统。
Thumb指令集中没有:乘加指令、64位乘法指令、协处理器指令、数据交换指令、程序状态寄存器指令,而且指令的第二操作数受到限制,除了跳转指令B有条件执行功能外,其他指令均为无条件执行。 Thumb指令集有4大类:数据处理指令、跳转指令、Load/Store指令、软件中断指令。

97 数据处理指令1

98 数据处理指令2

99 跳转指令 格 式 功 能 B{cond} label PC=label;
格 式 功 能 B{cond} label PC=label; 若有cond,则label必须在当前指令的-256~+256字节范围内; 否则,label必须在当前指令的-2K~+2K字节范围内 BL label R14=PC+4,PC=label; label必须在当前指令的-4M~+4M字节范围内 BX Rn PC=Rn,且切换处理器状态

100 Load/Store指令 1

101 Load/Store指令 2

102 软件中断指令 格 式 功 能 SWI 8位立即数 8位立即数为中断号

103 位操作指令应用 ;将R2中高8位数据传送到R3的低8位中。 MOV R0, R2, LSR #24
ORR R3, R0, R3, LSL #8

104 用移位实现乘法应用 MOV R0, R0, LSL #n ; R0=R0<<n; R0=R0*(2**n)
ADD R0, R0, R0, LSL #n ; R0=R0+R0*(2**n) RSB R0, R0, R0, LSL #n ; R0= R0*(2**n) - R0

105 64位数据加减运算应用 ;假设,R1R0存放一个64位数据,R3R2存放另一个64位数据。 64位数据加法运算
ADDS R0, R0, R2 ADC R1, R1, R3 64位数据减法运算 SUBS R0, R0, R2 SBC R1, R1, R3

106 数据变换应用 ;已知:R0=A B C D, 转换目标:R0= D C B A 程序一:
EOR R1, R0, R0, ROR #16 ;R1=A^C, B^D, C^A, D^B BIC R1, R1, #0xFF ;R1=A^C, 0, C^A, D^B MOV R0, R0, ROR # ;R0=D, A, B, C EOR R0, R0, R1, LSR #8 ;R0=D, C, B, A 程序二: MOV R2, #0xFF ;R2=0xFF ORR R2, R2, #0xFF ;R2=0x00FF00FF AND R1, R2, R ;R1=0 B 0 D AND R0, R2, R0, ROR #24 ;R0=0 C 0 A ORR R0, R0, R1, ROR # ;R0=D C B A

107 条件执行举例 ;求最大公约数 C语言代码: int gcd (int a, int b) { while (a != b)
if ( a > b ) a = a – b; else b = b – a; return a; } 对应的ARM代码段:R0=a, R1=b gcd CMP R0, R ;比较a和b大小 SUBGT R0, R0, R1 ;if (a>b) a=a-b (if a= = b do nothing) SUBLT R1, R1, R0 ;if (b>a) b=b-a (if a= = b do nothing) BNE gcd ;if (a!=b) then-跳转到gcd处继续执行 MOV PC, LR ;子程序结束,返回

108 条件判断语句 C语言代码: if ( a = = 0 || b = = 1) c = d + e ; 对应的ARM代码段:
CMP R0, #0 ;判断R0是否等于0 CMPNE R1, #1 ;如果R0不等于0,判断R1是否等于1 ADDEQ R2, R3, R4 ;R0=0或R1=1时,R2=R3+R4

109 循环语句 MOV R0, #loopcount Loop …… SUBS R0, R0, #1 BNE loop

110 复习题 1. 编写1+2+3+…+100的汇编程序。 2. 如何实现128位数的减法,举例说明。
3. 将存储器中起始地址M1处的4个字数据移动到地址M2处。 4. 参考CPSR寄存器中各标志位的含义,使处理器工作于系统模式。 5. 用跳转指令实现两段程序间的来回切换。


Download ppt "第3章 ARM寻址方式与指令系统 ARM编程模型 ARM指令格式和寻址方式 ARM指令集 Thumb指令集."

Similar presentations


Ads by Google