207
嵌嵌嵌嵌 嵌嵌 嵌3嵌 ARM 嵌嵌嵌嵌嵌嵌 2007.3

嵌入式系统讲义 第 3 章 ARM 指令系统

  • Upload
    brinda

  • View
    158

  • Download
    0

Embed Size (px)

DESCRIPTION

嵌入式系统讲义 第 3 章 ARM 指令系统. 周国运 2007.3. 第 3 章 ARM 指令系统. 主要内容 3.1 ARM 指令结构 3.2 ARM 寻址方式 3.3 ARM 指令集 3.4 Thumb 指令集 3.5 ARM 伪指令 3.6 ARM 汇编语言程序设计. 3.1 ARM 指令系统概述. 主要内容 一、指令系统概念 二、 ARM 指令的特点 三、 ARM 指令的格式 四、指令的条件码. 3.1 ARM 指令系统概述. 一、指令系统概念 指令: 是规定计算机进行某种操作的命令。 - PowerPoint PPT Presentation

Citation preview

Page 1: 嵌入式系统讲义 第 3 章   ARM 指令系统

嵌入式系统讲义

第 3 章 ARM 指令系统

周国运2007.3

Page 2: 嵌入式系统讲义 第 3 章   ARM 指令系统

第 3 章 ARM 指令系统

主要内容3.1 ARM 指令结构3.2 ARM 寻址方式3.3 ARM 指令集3.4 Thumb 指令集3.5 ARM 伪指令3.6 ARM 汇编语言程序设

Page 3: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.1 ARM 指令系统概述

主要内容

一、指令系统概念 二、 ARM 指令的特点三、 ARM 指令的格式四、指令的条件码

Page 4: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.1 ARM 指令系统概述一、指令系统概念

指令:是规定计算机进行某种操作的命令。 指令系统:计算机能够执行的各种指令的集合。

二、 ARM 指令的特点– 所有指令都是 32 位的。– 大多数指令都在单周期内完成。– 所有指令都可以条件执行。– ARM 指令为 load/store 类型。– 基本指令仅 36 条,分成五类。– 有 7 种寻址方式。– 指令集可以通过协处理器扩展。

Page 5: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ARM 指令是加载 / 存储 (Load/Store) 型:也即指令集仅能处理寄存器中的数据,而且

处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载 / 存储指令来完成。

• ARM 指令可以分为五大类:数据处理指令、存储器访问指令、分支指令、

协处理器指令、杂项指令。• ARM 指令有 7 种寻址方式:

立即寻址、寄存器寻址、寄存器间接寻址、基址寻址、堆栈寻址 、块拷贝寻址、相对寻址。

Page 6: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、 ARM 指令的格式ARM 指令基本的语法格式为:<Opcode> {<cond>}{s} <Rd>, <Rn> {, <Operand2>}

– Opcode :指令操作码。– cond :指令的条件码。– S :决定指令的操作是否影响 cpsr 的值。– Rd :目标寄存器编码。– Rn :包含第一个操作数的寄存器编码。– Operand2 :第 2 操作数。

ARM 指令典型的编码格式为:(数据处理指令类)

Cond Opcode S Rn Rd Operand2

0111215161920212425272831 78

例:ADDS R2 , R1 , #1

SUBNES R2 , R1 , #0x20

LDR R0 , [R1]

Page 7: 嵌入式系统讲义 第 3 章   ARM 指令系统

四、指令的条件码 条件码的位数和位置:每条 ARM 指令包含 4 位条件码域 <cond>, 它占用指令编码的最高四位 [31 : 28] 。 条件码的表示:条件编码共 24 = 16 种,其中,15 种用于指令的条件码。每种条件码用 2 个英文缩写字符表示。(见 P47 表 2-6 ) 带条件指令的执行: ARM 处理器根据指令的执行条件是否满足,决定当前指令是否执行。

只有在 cpsr 中的条件标志位满足指定的条件时,指令才会被执行。不符合条件的代码依然占用一个时钟周期(相当于一个 NOP 指令)。 条件码的书写方法:条件码的位置在指令助记符的后面(因此也称为条件后缀)。

例如: MOVEQ R0, R1

Page 8: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令条件码表条件码 助记符 含 义 标 志

0000 EQ 相等 Z=10001 NE 不相等 Z=00010 CS/HS 无符号数大于或等于 C=10011 CC/LO 无符号数小于 C=00100 MI 负数 N=10101 PI 非负数 N=00110 VS 溢出 V=10111 VC 没有溢出 V=01000 HI 无符号数大于 C=1 且 Z=01001 LS 无符号数小于或等于 C=0 或 Z=11010 GE 有符号数大于或等于 N=V1011 LT 有符号数小于 N!=V1100 GT 有符号数大于 Z=0 且 N=V1101 LE 有符号数小于或等于 Z=1 或 N!=V1110 AL 无条件执行 任意1111 保留 v5 以下版本总执行 ,v5 及以上版本有

Page 9: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2 ARM 寻址方式

主要内容一、立即寻址二、寄存器寻址三、寄存器间接寻址四、基址寻址五、堆栈寻址 六、块拷贝寻址七、相对寻址

Page 10: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2 ARM 寻址方式

寻址方式:处理器根据指令中给出的(地址)信息,寻找操作数(物理地址)的方式。

我们将 ARM 指令系统的寻址方式分为 7 种(有分为 9种的等)。

Page 11: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.1 立即寻址立即寻址也叫立即数寻址。立即寻址概念:操作数本身就在指令中给出,

只要取出指令也就取到了操作数。这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。

ADD R0 , R0 ,# 1 ; R0←R0+ 1

MOV R0 ,# 0x3f ; R0←# 0x3f书写立即数时,要求以“#”为前缀。• 十六进制数,#后加 0x或 &, 如 #0x3f,#&3f.• 二进制数, #后加 0b, 如 #0b1011• 十进制数, #后加 0d 或缺省 , 如 #0d678,#789 如何构造 32 位立即数?

Page 12: 嵌入式系统讲义 第 3 章   ARM 指令系统

在指令格式中,第二个操作数有 12 位:

因此有效立即数 immediate 可以表示成: <immediate>=immed_8 循环右移( 2×rot )

4 bit 移位值 (0-15)乘于 2 ,得到一个范围在0-30 ,步长为 2 的移位值。

因此,将 ARM 中的立即数称为 8 位位图。记住一条准则: “最后 8 位移动偶数位”得

到立即数。

Immed_8rot……12 11 8 7 0

Shifter ROR immediate

Page 13: 嵌入式系统讲义 第 3 章   ARM 指令系统

031ror #0

ror #8

ror #30

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

7例:

下列命令中,汇编器把立即数转换为移位操作:

MOV R0,#4096 ; uses 0x40 ror 26 ADD R1,R2,#0xFF0000 ; uses 0xFF ror 16

带有立即数的 MOV 指令的二进制编码为:MOV R0 , #0xF200 ; E3A00CF2.

MOV R1 , #0x110000 ; E3A01811.

MOV R4 , #0x12800 ; E3A04B4A.

0xF200 =0xF2循环右移( 2*C )

0x110000 =0x11循环右移( 2*8 )

0x12800 =0x4A循环右移( 2*B )

Page 14: 嵌入式系统讲义 第 3 章   ARM 指令系统

只有能够通过此构造方法得到的才是合法的立即数。– 合法立即数:

• 0xFF; 0x104 (其 8 位图为 0x41 ); 0xFF0; 0xFF00

– 非法立即数:• 0x101; 0x102; 0xFF1

深入理解:一个合法的立即数可能有多种编码方法,将使某些指令的执行产生不同的结果。 如

0x3F0

ARM 汇编编译器生成立即数的规则为:– 当立即数数值在 0到 0xFF范围时,令 immed_8=<immed

iate> , rot=0 。– 其它情况下,汇编编译器选择使 rot 数值最小的编码方式。

immed_8=0x3F , rot=0xE ,对 3F左移 4位

immed_8=0xFC , rot=0xF ,对 FC左移2 位

Page 15: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.2 寄存器寻址寄存器寻址:

——利用寄存器中的数值作为操作数。这种寻址方式是各类微处理器经常采用的一种方

式,也是一种执行效率较高的寻址方式。两种具体形式:寄存器寻址、寄存器移位寻址。一、寄存器寻址

如指令:

ADD R0 , R1 , R2 ; R0←R1+ R2

Page 16: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、寄存器移位寻址 1 、寄存器移位寻址

当第二操作数为寄存器型时,在执行寄存器寻址操作时,也可以对第二操作数寄存器进行移位,此时第二操作数形式为:

MOV Rd, Rn, Rm , {<shift>}

其中: Rm 称为第二操作数寄存器<shift> 用来指定移位类型和移位位数,有两种形式:

5 位立即数 (其值小于 32 ) 寄存器 ( 用 Rs 表示 ) (其值小于 32 )

在指令执行时将寄存器移位后的内容作为第二操作数参与运算。例如指令:

ADD R3 , R2 , R1 , LSR #2 ; R3←R2+(R1右移 2位 )

ADD R3 , R2 , R1 , LSR R0 ; R3←R2+(R1右移R0 位 )

Page 17: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、第二操作数移位方式共有 6 种移位方式:

• — LSL 逻辑左移 — LSR 逻辑右移 • — ASL 算术左移— ASR 算术右移 • — ROR 循环右移 — RRX 带扩展的循环右移

( 1 ) LSL :逻辑左移,空出的最低有效位用 0填充。

031 0

0

( 2 ) LSR :逻辑右移,空出的最高有效位用 0填充。 31 0

SUB R3 , R2 , R1 , LSL #2 ; R3←R2-(R1左移 2位 )SUB R3 , R2 , R1 , LSR R0 ; R3←R2-(R1右移 R0 位 )

Page 18: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 3 ) ASL :算术左移,由于左移空出的有效位用 0填充,因此它与 LSL同义。

( 4 ) ASR :算术右移 (Arithmetic Shift Right) 。算术移位的对象是带符号数,移位过程中必须保持操作数的符号不变。如果源操作数是正数,空出的最高有效位用 0 填充,如果是负数用 1填充。

30 0

ADD R3 , R2 , R1 , ASL #2 ; R3←R2+(R1左移 2 位 )

SUB R3 , R2 , R1 , ASR R3 ; R3←R2-(R1 算术右移 R3

位 )

Page 19: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 5 ) ROR :循环右移 (Rotate Right) ,移出的字的最低有效位依次填入空出的最高有效位。

31 0

( 6 ) RRX :带进位位的循环右移 (Rotate Right Extended) 。将寄存器的内容循环右移 1 位,空位用原来 C标志位填充。 31 0

C

SUB R3 , R2 , R1 , ROR #2 ; R3←R2+(R1循环右移 2 位 )

SUB R3 , R2 , R1 , RRX R0; R3←R2-(R1 带进位位循环右移 R0 位 )

Page 20: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、第二操作数的移位位数

移位位数可以用立即数方式或者寄存器方式给出,其值均小于 32 ,应为 0---31 。

如下所示:

ADD R3 , R2 , R1 , LSR #2 ; R3R2+(R1右移 2 位 )

ADD R3 , R2 , R1 , LSR R4 ; R3R2+(R1右移 R4位 )

寄存器 R1 的内容分别逻辑右移 2 位、 R4 位 ,再与寄存器 R2 的内容相加,结果放入 R3 中。

Page 21: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.3 寄存器间接寻址寄存器间接寻址——就是以寄存器中的值作为操作数的地址,而操

作数本身存放在存储单元中。例如以下指令:

LDR R0 , [R1] ;R0←[R1] STR R0 , [R1] ;[R1]←R0

第一条指令将以 R1 的值为地址的存储单元中的内容加载到寄存器 R0 中。

第二条指令将 R0 的内容存储到以 R1 的值为地址的存储单元中。 R1—— 基址寄存器 R1 的内容——基地址

Page 22: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.4 变址寻址一、变址寻址也叫基址加偏(变)址寻址 ——将基址寄存器的内容与指令中给出的地址偏

移量相加,得到操作数所在的存储器的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。

( 4K )

例如:LDR R0 , [R1 ,# 4] ; R0←mem32[R1

+ 4]

Cond Opcode Rn Rd Offset

0111215161920272831

Page 23: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、偏移地址方式有三种加偏址的方式1 、前变址模式(不修改基址寄存器):

——先基址 +偏址,生成操作数地址,做指令指定的操作。

也叫前索引偏移。

0x05

R10x200基址

寄存器 0x200

R00x05

源 寄存器

偏移量12 0x20C

Pre-indexed: STR r0,[r1,#12]

Page 24: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、自动变址模式 (修改基址寄存器 ) : ——①先基址 +偏移,生成操作数地

址,做指令指定的操作。②然后自动修改基址寄存器。

• 例如:LDR R0 , [R1 ,# 4]! ; R0←mem32 [R

1+ 4]; R1←R1+ 4

! ——表示更新基址寄存器。

Page 25: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、后变址模式 (修改基址寄存器 ) : ——①基址寄存器不加偏移作为操作数地址。 ②完成指令操作后,用 ( 基址 +偏移 ) 的值修改基址寄存器。

即先用基地址传数,然后修改基地址(基址+偏移),也叫后索引偏移。

0x5r10x200

原基址寄存器 0x200

r00x5

源 寄存器

偏移量12 0x20c

r10x20c

更新基址寄存器

例 Post-indexed: STR r0,[r1],#12

Page 26: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、偏移地址形式 ——可以是一个立即数,也可以是另一个

寄存器,并且还可以是寄存器移位操作。如下所示:LDR r0 , [r1 , r2] ; r0<—mem32[r1+r2]

LDR r0 , [r1 , r2 , LSL #2]; r0<—mem32[r1+r2*4]

常用的是立即数偏移的形式。

Page 27: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.5 堆栈寻址

堆栈寻址 ——堆栈寻址是隐含的,它使用一个专门的

寄存器(堆栈指针 SP )指向一块存储区域( 堆栈 ) 。

堆栈可分为两种增长方式:向上生长:向高地址方向生长,称为递

增堆栈。向下生长:向低地址方向生长,称为递

减堆栈。

Page 28: 嵌入式系统讲义 第 3 章   ARM 指令系统

根据堆栈指针指向的数据位置的不同,可分为:• 满堆栈 ——堆栈指针指向最后压入堆栈的有效数据项,

称为满堆栈;• 空堆栈

——堆栈指针指向下一个待压入数据的空位置,称为空堆栈。

这样就有 4 种类型的堆栈表示递增和递减的满和空堆栈的各种组合。

Page 29: 嵌入式系统讲义 第 3 章   ARM 指令系统

四种类型的堆栈工作方式 • 满递增堆栈 FA ( Full Ascending ):——堆栈指针指向最后压入的数据,且由低地址向高地址生长。

• 满递减堆栈 FD : ——堆栈指针指向最后压入的数据,且由高地址向低地址生长。

• 空递增堆栈 EA : ——堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生长。

• 空递减堆栈 ED ( Empty Descending ): ——堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生长。

Page 30: 嵌入式系统讲义 第 3 章   ARM 指令系统

r4 100r5 FFr6 1234r7 A0BE

lr 8034

ABCD8765102E

16FFFF1010123484209753 高地址

LDMFA sp!,{r4-r7,pc}满递增

SP100FF

1234AOBE80341010123484209753

r4 1r5 14544r6 0r7 12

pc 9020

r4 100100FF r5 FF

1234 r6 1234A0BE r7 A0BE8034

pc 8034

Old SP

100FF

1234A0BE8034

SP

Old SP

100FF1234A0BE8034

STMFD sp!,{r4-r7,lr}满递减

8034……

第 5次到此

Page 31: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.6 块拷贝寻址一、块拷贝寻址——把存储器中的一个数据块加载到多

个寄存器中,或者是把多个寄存器中的内容保存到存储器中。

应用指令:块拷贝寻址是多寄存器传送指令 LDM/STM 的寻址方式,因此也叫多寄存器寻址。

块拷贝寻址操作中的寄存器,可以是 R0-R15这 16 个寄存器的子集(一部分),或是所有寄存器。

Page 32: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、 4 种寻址操作LDMIA / STMIA Increment After(先传送,后地址加 4)

LDMIB / STMIB Increment Before(先地址加 4 , 后传送 )

LDMDA / STMDA Decrement After(先传送,后地址减 4)

LDMDB / STMDB Decrement Before (先地址减 4, 后传送 )

IA

r1地址增加

r4

r0

r1r4

r0

r1r4

r0 r1r4

r0

r10

IB DA DBSTMxx r10, {r0,r1,r4}

基址寄存器 (Rn)

地址递减,指针最后位置

地址递增,指针最后位置

Page 33: 嵌入式系统讲义 第 3 章   ARM 指令系统

栈生长 地址 顶空满 增减次序

栈、块递增 栈、块递减

顶满 顶空 顶满 顶空

地址增加

先增 STMIB

STMFA

LDMIB

LDMED

后增 STMIA

STMEA

LDMIA

LDMFD

地址减少

先减 LDMDB

LDMEA

STMDB

STMFD

后减 LDMDA

LDMFA

STMDA

STMED

多寄存器 load 和 stroe 指令的堆栈和块拷贝对照

STMFA ( Full 、 Add ):栈满递增。 F--- 栈顶满空; A--- 栈增减LDMIB* ( Inc 、 Befo ):块先增地址、再传数。

Page 34: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.2.7 相对寻址相对寻址—— 与基址变址寻址方式相类似,相对寻址

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

相对寻址指令举例如下: BL SUBRl ;调用到 SUBRl子程

序 . . . ; SUBRl应为 24 位有符号数SUBR1 …

…MOV PC, LR ;返回

Page 35: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3 ARM 指令集主要内容

1 、存储器访问指令2 、数据处理指令3 、分支指令4 、协处理器指令5 、杂项指令6 、 ARM 伪指令

Page 36: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.1 存储器访问指令ARM微处理器用加载 / 存储指令访问存储器,

实现在寄存器和存储器之间传送数据。加载指令用于将存储器中的数据传送到寄存器,存储指令则完成相反的操作。

由于 ARM 处理器对外设寄存器、 I/O映射空间与存储器统一编址,因此,对外围设备的 I/O 操作也用此类指令。

基本的加载 / 存储指令仅有 5 条,分为 3 种:— LDR 和 STR ,单寄存器加载 / 存储指令— LDM 和 STM ,多寄存器加载 / 存储指令— SWP ,寄存器和存储器数据交换指令

Page 37: 嵌入式系统讲义 第 3 章   ARM 指令系统

一、单寄存器的存取指令 单寄存器加载 / 存储指令是 ARM 在寄存

器和存储器间传送单个字节和字的最灵活方式。根据传送数据的类型不同,单个寄存器

存取指令又可以分为以下两类:– 单字和无符号字节的加载 / 存储指

令– 半字和有符号字节的加载 / 存储指

Page 38: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、单字和无符号字节的加载/存储指令

• LDR :指令从内存中取 32 位字或 8 位无符号字节数

据放入寄存器;• STR :

指令将寄存器中的 32 位字或 8 位无符号字节数据保存到存储器中。

• 注意:– 无符号字节加载时,用 0将 8 位的操作数扩展到 32 位。

Page 39: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 1 )指令格式

LDR{cond}{T} Rd , <地址 > ;加载指定地址上的字数据,放入 Rd 中。

STR{cond}{T} Rd , <地址 > ;存储 Rd 中字数据,到指定地址的存储单

元。

LDR{cond}B{T} Rd , <地址 > ;加载字节数据到 Rd 中 , Rd 最低字节有效,

高 24 位为 0 。 STR{cond}B{T} Rd , <地址 >

;存储 Rd 中字节数据, Rd 中最低字节为传送数据。

Page 40: 嵌入式系统讲义 第 3 章   ARM 指令系统

• T 后缀– T 为可选后缀,若指令有 T ,那么即使处理器是

在特权模式下,存储系统也将访问看成是处理器是在用户模式下。

– 用于存储器保护。– 不能与前变址模式、自动变址模式一起使用(即

不能改变基址寄存器值)。– T 在用户模式下无效。

Page 41: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 2 )操作数寻址方式

LDR/STR 指令为变址寻址,由两部分组成:– 基地址部分:为一个基址寄存器,可以为任一个通用

寄存器;– 偏移地址部分:这一部分非常灵活,实际就是第二个

操作数,可以有以下 3 种格式:• 立即数• 寄存器• 寄存器及移位常数。

Page 42: 嵌入式系统讲义 第 3 章   ARM 指令系统

① 立即数——12 位立即数可以是一个无符号的数值。

这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

指令举例如下:• LDR R1 , [R0 , #0x12] ;将 R0+0x12地址处的数据读出,保存到 R1 中 (R0 的值

不变 )

• LDR R1 , [R0 , # -0x12]

;将 R0-0x12地址处的数据读出,保存到 R1 中 (R0 的值不变 )

Page 43: 嵌入式系统讲义 第 3 章   ARM 指令系统

② 寄存器——寄存器中的数值可以加到基址寄存器,

也可以从基址寄存器中减去这个数值。指令举例如下:

• LDR R1 , [R0 , R2]

;将 R0+R2地址处的数据读出,保存到 R1 中

• LDR R1 , [R0 , -R2]

;将 R0-R2地址处的数据读出,保存到 R1 中

Page 44: 嵌入式系统讲义 第 3 章   ARM 指令系统

③ 寄存器及移位常数——寄存器移位后的值可以加到基址寄存

器,也可以从基址寄存器中减去这个数值。

指令举例如下:• LDR R1 , [R0 , R2 , LSL #2]

;将 R0+R2×4地址处的数据读出,保存到R1 中 (R0 、 R2 的值不变 )

• LDR R1 , [R0 , -R2 , LSL #2] ;将 R0-R2×4地址处的数据读出,保存到 R

1 中 (R0 、 R2 的值不变 ) 注意:移位位数只能是 5 位的立即数,不

能使用寄存器指定移位位数。

Page 45: 嵌入式系统讲义 第 3 章   ARM 指令系统

④ PC (即 R15 )使用的几个问题• 使用 PC 作为基址时,使用的数值是指令的地

址加 8 个字节(取指与执行相差 8 个字节)。• PC 不能用做偏移寄存器,也不能用于任何变

址寻址模式。• 把一个字加载到 PC ,将使程序转移到所加载

的地址,这是一个公认的实现跳转的方法。但是应当避免将一个字节加载到 PC 。

• 把 PC 存到存储器的操作在不同体系结构的处理器中产生不同的结果,应尽可能避免。

Page 46: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、半字和有符号字节的加载/存储指令

这类 LDR/STR 指令可实现半字(有符号和无符号)、有符号字节数据的传送。

特点:– 偏移量格式、寻址方式与加载/存储字和无符号字节指

令基本相同。– 立即数偏移量限定在 8 位,寄存器偏移量不可经过移位得到。

Page 47: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 1 )指令格式如下 LDR {cond}H Rd , <地址 >

;加载无符号半字数据到 Rd 的低 16 位 ,高 16 位清零。

LDR {cond}SB Rd , <地址 > ;加载指定地址上有符号字节到 Rd 中,

高 24 位用符号位扩展LDR {cond}SH Rd , <地址 >

;加载指定地址上的有符号半字到 Rd 中,高 16 位用符号位扩展。

STR{cond}H Rd , <地址 > ;存储 Rd 中的低 16 位半字数据。 存储有符号数据和无符号数据之间没有差别。

Page 48: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 2 )两点说明:– 符 号 位——有符号字节或有符号半字的加载,

用“符号位”扩展到 32 位;无符号半字传送是用 0 扩展到 32 位。

– 地址对齐——对半字传送的地址必须为偶数。非半字对齐的半字加载将使 Rd 内容不可靠;非半字对齐的半字存储将使指定地址的 2 字节存储内容不可靠。

Page 49: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 3 )指令举例LDRSB R1 , [R0 , R3]

;将 R0+R3地址上的字节数据读到 R1,高 24 位用符号位扩展。

LDRSH R1 , [R9] ;将 R9地址上的半字数据读出到 R1 ,高 16位用符号位扩展。

LDRH R6 , [R2] , #2 ;将 R2地址上的半字数据读出到 R6 ,

高 16 位用零扩展,然后修改 R2=R2+2 。STRH R1 , [R0 , #2]!

;将 R1 的数据保存到 R0+2地址中,只存储低 2 字节数据,并且修改 R0=R0+2 。

Page 50: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、多寄存器的存取指令 LDM 和 STM 指令可以实现在一组寄存器和

一块连续的内存单元之间存 /取数据。LDM 为加载多个寄存器; STM 为存储多

个寄存器。这两条指令,允许传送 16 个寄存器 R0---R

15 的任何子集或所有寄存器。1 、指令格式

• LDM{cond}<模式 > Rn{!} , <reglist>{^}• STM{cond} <模式 > Rn{!} , <reglist>{^}

Page 51: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、指令格式说明( 1 ) Rn :表示基址寄存器,装有传送数据的初始地址, Rn 不允许为 R15 (即 PC )。( 2 ) Rn 后缀“ !” :表示最后的地址写回到 Rn中。( 3 ) Reglist :表示寄存器列表,可包含多个序号连续的或者分离的寄存器,用“,”分开。

– 格式例子: {R1 , R2 , R6~R9}

– 列表寄存器和存储器地址的关系规则:编号低的寄存器对应于存储器中低地址单

元,编号高的寄存器对应于存储器中高地址单元。

Page 52: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 4 )后缀“ ^”说明– 寄存器列表不包含 PC :使用后缀“ ^” 进行数据传送且时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。

– 寄存器列表包含有 PC :除了正常的多寄存器传送外,还要将 SPSR 拷贝到 CPSR 中。

该用法可用于异常处理返回。– 禁用情况:后缀“ ^” 不允许在用户模式或系统模式下使用。 ,因为它们没有 SPSR

Page 53: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 5 )当 Rn 在寄存器列表中且使用后缀“ !”– 对于 STM 指令,若 Rn 为寄存器列表中的最低数

字的寄存器,则会将 Rn 的初值保存;– 其它情况下 Rn 的加载值和存储值不可预知。

( 6 )地址字对齐——这些指令寻址是字对齐的,即忽略

地址位 [1:0] 。

Page 54: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 7 )关于模式项LDM/STM 的主要用途是现场保护、数据复

制和参数传送等。其模式有如下 8 种(前面 4 种用于数据块的传输(为存储操作) , 后面 4 种是堆栈操作) :

• IA : 先传、后地址加 4;• IB : 先地址加 4 、后传;• DA :先传、后地址减 4;• DB :先地址减 4 、后传;• FD : 满递减堆栈,先地址减 4 、后传,与 DB 对应;• ED : 空递减堆栈,先传、后地址减 4 ,与 DA 对应;• FA : 满递增堆栈,先地址加 4 、后传,与 IB 对应;• EA : 空递增堆栈,先传、后地址加 4 ,与 IA 对应。

Page 55: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 7 )关于模式项LDM/STM 的主要用途是现场保护、数据复

制和参数传送等。其模式有如下 8 种(前面 4 种用于数据块的传输(为加载寄存器 ) ,后面 4 种是堆栈操作) :

• IA : 先传、后地址加 4;• IB : 先地址加 4 、后传;• DA :先传、后地址减 4;• DB :先地址减 4 、后传;• FD : 满递减堆栈,先减地址、后传,与 IA 对应;• ED : 空递减堆栈,先传、后减地址,与 IB 对应;• FA : 满递增堆栈,先加地址、后传,与 DA 对应;• EA : 空递增堆栈,先传、后加地址,与 DB 对应。

Page 56: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、应用举例• LDMIA R0! , {R3 - R9} ;加载 R0 指向地址上的多字数据,保存到 R3~R

9 中, R0 值更新。• STMIA R1! , {R3 - R9} ;将 R3~ R9 的数据存储到 R1 指向的地址上,

R1 值更新 。• STMFD SP! , {R0 - R7 , LR} ;现场保存,将 R0~ R7 、 LR 入栈, SP 值更新 。

• LDMFD SP! , {R0 - R7 , PC} ;恢复现场,包括 CPSR ,异常处理返回, SP

值更新。

Page 57: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、单寄存器交换指令( SWP )SWP 指令用于将一个存储单元 (该单元地址放在寄

存器 Rn 中 ) 的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该存储单元中。

1 、指令格式SWP{cond}{B} Rd , Rm , [Rn]

– B 为可选后缀,若有 B ,则交换字节,否则交换 32 位字

– Rd 为被加载的寄存器– Rm 的数据用于存储到 Rn 所指的地址中

若 Rm与 Rd 相同,则为寄存器与存储器内容进行交换

– Rn 为要进行数据交换的存储器地址, Rn 不能与 Rd 和Rm 相同。

Page 58: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、指令举例• SWP R1 , R1 , [R0]

;将 R1 的内容与 R0 指向的存储单元的内容进行交换。

• SWPB R1 , R2 , [R0]

;将 R0 指向的存储单元的内容读取 1字节数据到 R1 中 ( 高 24 位清零 ) ,并将 R2的内容写入到该内存单元中 ( 最低字节有效 )

Page 59: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.2 数据处理指令

主要内容

1 、数据处理指令概述2 、算术运算指令3 、逻辑运算指令4 、数据传送指令5 、比较指令6 、测试指令

Page 60: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.2.1 数据处理指令概述1 、 ARM 数据处理指令的功能

主要完成寄存器中数据的算术和逻辑运算操作。

2 、 ARM 数据处理指令的特点– 操作数来源:所有的操作数要么来自寄存器,要么

来自立即数,不会来自存储器。– 操作结果:如果有结果,则结果一定是为 32 位宽、

或 64 位宽(长乘法指令),并且放在一个或两个寄存器中,不会写入存储器。

– 有第二个操作数(除了乘法指令) Operand2 :切记其三种形式:立即数、寄存器、寄存器移位。

– 乘法指令的操作数:全部是寄存器。

Page 61: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 ARM 数据处理指令分类

22 条可分为 5 类:– 算术运算指令: ADD ADC

SUB SBC RSB RSC

MUL MLA UMULL UMLAL SMULL SMLAL

– 逻辑运算指令: AND ORR EOR BIC– 数据传送指令: MOV MVN– 比较指令: CMP CMN– 测试指令: TST TEQ

上述指令只能对寄存器操作,不能针对存储器。

Page 62: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、数据处理指令对程序状态寄存器 CPSR 的影响

( 1 )选择“ S” 后缀问题:指令中可以选择 s 后缀,以影响状态标志。但是

比较指令( cmp 、 cmn 、 tst 和 teq )不需要后缀 S ,它们总会直接影响 CPSR 中的状态标志。

( 2 )对 CPSR 中标志位的影响:– N标志位:如果结果为负,则N标志位置1;否则清0。– Z标志位:如果结果为0,则Z标志位置1;否则清0。– C标志位:如果是加、减运算指令或比较指令时,C标志位

设置为ALU的进位输出;否则设置为移位器的移位输出。如果不需要移位,则C保持不变。

– V标志位:在非加减操作中,V标志位保持原值。在加减操作中,如果有溢出,则置1;不发生溢出,则清0。

Page 63: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 3 )关于恢复 CPSR原值问题:如果指令带有 S 后缀(除了比较指令以外),同

时又以 PC 为目标寄存器进行操作,• 在异常模式下:则操作的同时从 SPSR恢复 CPS

R 。比如:– movs pc, #0xff /* cpsr = spsr; pc = 0xff */

– adds pc, r1, #0xffffff00

/* cpsr = spsr; pc = r1 + 0xffffff00 */

– ands pc, r1, r2 /* cpsr = spsr; pc = r1 & r2; */

• 在 user 或者 system模式:会产生不可预料的结果,因为在这两种模式下没有 SPSR 。

Page 64: 嵌入式系统讲义 第 3 章   ARM 指令系统

数据处理指令的二进制编码

add r0, r1, #0xff

add r0, r1, r1, LSL r2

add r0, r1, r1, LSL #31

Page 65: 嵌入式系统讲义 第 3 章   ARM 指令系统

5 、数据处理指令的详细列表(未含 6 条乘法指令)

操作码 [24 : 21] 助记符 意 义 效 果0000 AND 逻辑位与 Rd = Rn AND Op2

0001 EOR 逻辑位异或 Rd = Rn EOR Op2

0010 SUB 减 Rd = Rn - Op2

0011 RSB 反向减 Rd = Op2 – Rn

0100 ADD 加 Rd = Rn + Op2

0101 ADC 带进位加 Rd = Rn + Op2 + C

0110 SBC 带进位减 Rd = Rn - Op2 + C -1

0111 RSC 反向带进位减 Rd = Op2 - Rn + C -1

1000 TST 测试 根据 Rn AND Op2 设置条件码1001 TEQ 测试相等 根据 Rn EOR Op2 设置条件1010 CMP 比较 根据 Rn - Op2 设置条件码

1011 CMN 负数比较 根据 Rn + Op2 设置条件码1100 ORR 逻辑位或 Rd = Rn OR Op2

1101 MOV 传送 Rd = Op2

1110 BIC 位清零 Rd = Rn AND NOT Op2

1111 MVN 求反 Rd = NOT Op2

Page 66: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.2.2 算术运算指令一、加减运算指令1 、 ADD—— 加法运算指令指令格式

  ADD{cond}{S} Rd , Rn , operand2    ADD 指令将 operand2 的数据与 Rn 的值相加,

结果保存到 Rd 寄存器。

指令举例ADDS R1 , R1 , #1       ; R1 = R1+1ADDS R3 , R1 , R2 , LSL #2  ; R3 = R1+R2<<2

Page 67: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 ADC—— 带进位加法指令

指令格式ADC{cond}{S} Rd , Rn , operand2

   ADC 指令将 operand2 的数据与 Rn 的值相加,再加上 CPSR 中的 C 条件标志位,结果保存到 Rd 寄存器。

指令举例ADDS R4 , R0 , R2 ;使用 ADC实现 64 位加法ADC R5 , R1 , R3 ; (R5 、 R4) = (R1 、 R0)+(R3 、 R2)

Page 68: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 SUB——减法运算指令

指令格式SUB{cond}{S} Rd , Rn , operand2

SUB 指令用寄存器 Rn减去 operand2 ,结果保存到 Rd 中。

指令举例

SUBS R0 , R0 , #l ; R0 = R0-1

SUB R6 , R7 , #0x10 ; R6 = R7-0x10

Page 69: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 SBC—— 带进位减法指令

指令格式SBC{cond}{S} Rd , Rn , operand2

SBC 指令用寄存器 Rn减去 operand2 ,再减去CPSR 中的 C 条件标志位的反码,结果保存到 Rd中。

指令举例SUBS R4 , R0 , R2 ;使用 SBC实现 64 位减法,SBC R5 , R1 , R3 ; (R5,R4) = (R1,R0)-(R3,R2)

Page 70: 嵌入式系统讲义 第 3 章   ARM 指令系统

5 、 RSB——反向减法指令

指令格式如下:RSB{cond}{S} Rd , Rn , operand2

RSB 指令用寄存器 operand2减去 Rn ,结果保存到 Rd 中。

指令举例如下:

RSB R3 , R1 , #0xFF00 ; R3 = 0xFF00-R1RSBS R1 , R2 , R2 , LSL #2 ; R1R2<<2-R2

; (R1 =R2×3)

Page 71: 嵌入式系统讲义 第 3 章   ARM 指令系统

6 、 RSC—— 带进位反向减法指令

指令格式如下:RSC{cond}{S} Rd , Rn , operand2

RSC 指令用寄存器 operand2减去 Rn ,再减去CPSR 中的 C 条件标志位的反码,结果保存到 Rd 中。

指令举例如下:RSBS R2 , R0 , #0 ;求一个 32 位数的负数RSC R3 , R1 , #0 ;使用 RSC 指令实现

;求 64 位数值的负数

Page 72: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、乘法指令• ARM 有两类乘法指令:

– 32 位的乘法指令,即乘法操作的结果为 32 位;– 64 位的乘法指令,即乘法操作的结果为 64 位。

MUL Rd,Rm,Rs 32 位乘法指令MUA Rd,Rm,Rs,Rn 32 位乘加指令UMULL RdL,RdH,Rm,Rs,Rn 64 位无符号乘法UMAL RdL,RdH,Rm,Rs,Rn 64 位无符号乘加SMULL RdL,RdH,Rm,Rs,Rn 64 位有符号乘法SMULL RdL,RdH,Rm,Rs,Rn 64 位有符号乘加

Page 73: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、乘法指令• ARM 有两类乘法指令:

– 32 位的乘法指令,即乘法操作的结果为 32 位;– 64 位的乘法指令,即乘法操作的结果为 64 位。

助记符 说 明 操 作 条件码位置MUL Rd,Rm,Rs 32 位乘法指令 RdRm*Rs(Rd≠Rm)

MUA Rd,Rm,Rs,Rn 32 位乘加指令 RdRm*Rs+Rn (Rd≠Rm)

UMULL RdL,RdH,Rm,Rs,Rn

64 位无符号乘法(RdL,RdH)Rm*Rs

UMAL RdL,RdH,Rm,Rs,Rn 64 位无符号乘加(RdL,RdH)Rm*Rs

SMULL RdL,RdH,Rm,Rs,Rn64 位有符号乘法SMULL RdL,RdH,Rm,Rs,Rn64 位有符号乘加

Page 74: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、 MUL——32 位乘法指令

指令格式如下:MUL{cond}{S} Rd , Rm , Rs ; RdRm*Rs

MUL 指令将 Rm 和 Rs 中的值相乘,结果的低 32 位保存到 Rd 中。

指令举例如下:MUL R1 , R2 , R3 ; R1=R2×R3

MULS R0 , R3 , R7 ; R0=R3×R7 , ;设置 CPSR 的 N 位和 Z 位

Page 75: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 MLA——32 位乘加指令指令格式如下:

MLA{cond}{S} Rd , Rm , Rs , Rn ; RdRm*Rs+R

n

MLA 指令将 Rm 和 Rs 中的值相乘,再将乘积加上第 3 个操作数,结果的低 32 位保存到Rd 中。

指令举例如下: MLA R1 , R2 , R3 , R0 ; R1=R2×R3+R0

Page 76: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 UMULL—64 位无符号乘法指令

指令格式如下: UMULL{cond}{S} RdLo , RdHi , Rm , Rs

; RdHi, RdLo Rm*Rs

UMULL 指令将 Rm 和 Rs 中的值作无符号数相乘,结果的低 32 位保存到 RdLo 中,高 32 位保存到 RdHi 中。

指令举例如下: UMULL R0 , R1 , R5 , R8 ; (R1,R0)R5×

R8

Page 77: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 UMLAL—64 位无符号乘加指令

指令格式如下: UMLAL{cond}{S} RdLo , RdHi , Rm , Rs

; RdHi, RdLo Rm*Rs+ RdHi, RdLo

UMLAL 指令将 Rm 和 Rs 中的值作无符号数相乘, 64 位乘积与 RdHi 、 RdLo 相加,结果的低32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中。

指令举例如下: UMLAL R0 , R1 , R5 , R8

; (R1,R0)R5×R8+(R1,R0)

第 6次到此

Page 78: 嵌入式系统讲义 第 3 章   ARM 指令系统

5 、 SMULL—64 位有符号乘法指令

指令格式如下:SMULL{cond}{S} RdLo , RdHi , Rm , Rs

; RdHi, RdLo Rm*Rs

SMULL 指令将 Rm 和 Rs 中的值作有符号数相乘,结果的低 32 位保存到 RdLo 中,而高 32 位保存到 RdHi 中。

指令举例如下: SMULL R2 , R3 , R7 , R6 ; (R3,R2)R7×R

6

Page 79: 嵌入式系统讲义 第 3 章   ARM 指令系统

6 、 SMLAL—64 位有符号乘加指令

指令格式如下:SMLAL{cond}{S} RdLo , RdHi , Rm , Rs

; RdHi, RdLo Rm*Rs+ RdHi, RdLo

SMLAL 指令将 Rm 和 Rs 中的值作有符号数相乘, 64 位乘积与 RdHi 、 RdLo 相加,结果的低 32位保存到 RdLo 中,高 32 位保存到 RdHi 中。

指令举例如下:SMLAL R2 , R3 , R7 , R6 ; ; (R3,R2)R7×R6+(R3,R2)

Page 80: 嵌入式系统讲义 第 3 章   ARM 指令系统

7 、乘法指令的特点

① 不支持第 2 操作数为立即数。② 结果寄存器不能与第一源寄存器相同。

• Rd 、 RdHi 、 RdLo 不能与 Rm 为同一寄存器。

• RdHi 和 RdLo 不能为同一寄存器。③ 避免将 R15 定义为任一操作数或结果寄存器。④ 早期的 ARM 处理器仅支持 32 位乘法指令。 A

RM7 版本和后续的在名字中有 M 的处理器才支持 64 位乘法指令。

Page 81: 嵌入式系统讲义 第 3 章   ARM 指令系统

⑤ 对标志位的影响– 对 N 标志位:对有符号数乘法,若结果是 32 位

指令形式, Rd 的第 31 位是标志位 N;对于产生长结果的指令形式, RdHi 的第 31 位是标志位。

– 对 Z 标志位:如果 Rd 或 RdHi 、 RdLo 为 0 ,则标志位 Z 置位。

– 对 V 标志位:乘法指令不影响 V 标志位。– 对 C 标志位: ARM v5 及以上的版本不影响 C

标志位; ARM v5 以前的版本, C 标志位数值不确定。

Page 82: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.2.3 逻辑运算指令1 、 AND——逻辑“与”操作指令

指令格式如下:AND{cond}{S} Rd , Rn , operand2

AND 指令将 operand2 的值与寄存器 Rn 的值按位逻辑“与”操作,结果保存到 Rd 中。

指令举例如下:ANDS R0 , R0 , #0x01 ; R0 = R0&0x01

;取出最低位数据AND R2 , R1 , R3 ; R2 = R1&R3

AND 指令可用于提取寄存器中某些位的值。

Page 83: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 ORR——逻辑“或”操作指令

指令格式如下: ORR{cond}{S} Rd , Rn , operand2

ORR 指令将 operand2 的值与寄存器 Rn的值按位逻辑“或”操作,结果保存到 Rd 中。

指令举例如下: ORR R0 , R0 , #0x0F ;将 R0 的低 4 位置 1

ORR 指令用于将寄存器中某些位的值设置成 1 。

Page 84: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 EOR——逻辑“异或”操作指令

指令格式如下:EOR{cond}{S} Rd , Rn , operand2

EOR 指令将 operand2 的值与寄存器 Rn 的值按位逻辑“异或”操作,结果保存到 Rd 中。

指令举例如下: EOR R1 , R1 , #0x0F ;将 Rl 的低 4 位取反 EORS R0 , R5 , #0x01 ;将 R0R5异或 0x01 ,

;并影响标志位 EOR 指令可用于将寄存器中某些位的值取反。将某一位与 0异或,该位值不变;与 1异或,该位值被求反。

Page 85: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 BIC—— 位清除指令

指令格式如下:BIC{cond}{S} Rd , Rn , operand2

BIC 指令将寄存器 Rn 的值与 operand2 的值的反码按位逻辑“与”操作,结果保存到 Rd 中。

指令举例如下:BIC R1 , R1 , #0x0F ;将 R1 的低 4 位清 0 ,

;其它位不变 BIC 指令可用于将寄存器中某些位的值设置成 0 。将某一位与 1做 BIC 操作,该位值被设置成 0;将某一位与 0做 BIC 操作,该位值不变。

Page 86: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.2.4 数据传送指令

1 、 MOV—— 数据传送指令

( 1 )指令格式如下:MOV{cond}{S} Rd , operand2

MOV 指令将 operand2传送到目标寄存器 Rd 中。

( 2 )指令举例如下:MOVS R3 , R1 , LSL #2 ; R3 = R1<<2

;影响标志位MOV PC , LR ; PCLR ,子程序返回

Page 87: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 3 ) MOV 指令的功能– 寄存器之间传送。– 立即数传送到寄存器中。( 8 位立即数位图)– 实现单纯的移位操作。 MOV Rd , Rd , LSL ,

#3– 实现子程序调用、从子程序中返回。当 PC 寄存

器作为目标寄存器时可以实现程序跳转。– 实现把当前处理器模式的 SPSR 寄存器内容复制到 CPSR 中。

方法:当 PC 寄存器作为目标寄存器且指令中 S位被设置时,指令在执行跳转操作的同时,将当前处理器模式的 SPSR 寄存器内容复制到 CPSR 中。这样可以实现从某些异常中断中返回。

例子: MOVS PC , LR

Page 88: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 MVN—— 数据求反传送指令

指令格式如下:MVN{cond}{S} Rd , operand2

MVN 指令将 operand2按位取反后传送到目标寄存器 Rd 中。

指令举例如下:MVN R1 , #0xFF ; R10xFFFFFF00

MVN R1 , R2 ; Rl R2取反

Page 89: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、比较指令( 1 ) CMP——比较指令

指令格式如下:CMP{cond} Rn , operand2 CMP 指令将寄存器 Rn 的值减去 operand2 的值,根据操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。

指令举例如下:CMP R1 , #10 ; R1与 10比较,设置相关标志位

CMP 指令与 SUBS 指令的区别?

Page 90: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 2 ) CMN—— 负数比较指令

指令格式如下:CMN{cond} Rn , operand2

CMN 指令将寄存器 Rn 的值加上 operand2 的值,根据操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。

使用方法:一般 Rn 中存放的是欲比较的负数, operand2 为另一被比较的数。

指令举例如下:CMN R0 , #1 ; R0+1 ,判断 R0 是否为 1 的补码。

;若是,则 Z 位置 1 。CMN 指令与 ADDS 指令的区别:在于 CMN 指令不

保存运算结果。 CMN 指令可用于负数比较,比如“ CMN R0 , #1” 指令则表示 R0与 -1比较。若 R0 为 -1( 即 1 的补码 ) ,则 Z 置位;否则 Z复位

Page 91: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、测试指令( 1 ) TST—— 位测试指令

指令格式如下:TST{cond} Rn , operand2 TST 指令将寄存器 Rn 的值与 operand2 的值按位逻辑“与”操作,根据操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。

指令举例如下: TST R0 , #0x01 ;判断 R0 的最低位是否为 0 TST Rl , #0x0F ;判断 R1 的低 4 位是否为 0

TST 指令与 ANDS 指令的区别在于 TST 指令不保存运算结果。 TST 指令通常与 EQ 、 NE 条件码配合使用。当所有测试位均为 0 时, EQ 有效。而只要有一个测试位不为0 ,则 NE 有效。

Page 92: 嵌入式系统讲义 第 3 章   ARM 指令系统

( 2 ) TEQ——测试相等指令 指令格式如下:

TEQ{cond} Rn , operand2 TEQ 指令将寄存器 Rn 的值与 operand2 的值按位逻辑“异或”操作,根据操作的结果更新 CPSR 中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。

指令举例如下:TEQ R0 , R1 ;比较 R0与 R1 是否相等

; ( 不影响 V 位和 C 位 ) TEQ 指令与 EORS 指令的区别在于 TEQ 指令不保存运算结果。使用 TEQ 进行相等测试时,常与 EQ 、 NE 条件码配合使用。当两个数据相等时,EQ 有效;否则 NE 有效。

Page 93: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.3 分支指令概述在 ARM 中有两种方式可以实现程序的跳转:

– 一种是使用分支转移指令直接跳转;– 另一种则是直接向 PC 寄存器赋值来实现跳转。

ARM 的分支转移指令,可以从当前指令向前或向后的 32MB 的地址空间跳转,根据完成的功能它可以分为以下 4 种 : B 分支指令 BL 带链接的分支指令 BX 带状态切换的分支指令 BLX 带链接和状态切换的分支指令

Page 94: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、 B——转移指令

指令格式如下: B{cond} label

B 指令跳转到指定的地址执行程序。

指令举例如下: B WAITA ;跳转到WAITA 标号处 B 0x1234 ;跳转到绝对地址 0x1234 处

转移指令 B限制在当前指令的 ±32 MB的范围内。

Page 95: 嵌入式系统讲义 第 3 章   ARM 指令系统

例子:• 无条件跳转: B label …… label ……• 执行 10次循环:

MOV R0, #10 LOOP

…… SUBS R0 , R0, #1 BNE LOOP

Page 96: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 BL—— 带链接的转移指令

指令格式如下: BL{cond} label

BL 指令先将下一条指令的地址拷贝到 LR 链接寄存器中,然后跳转到指定地址运行程序。

指令举例如下: BL SUB1 ; LR 下条指令地址

;转至子程序 SUB1 处 …

SUB1 … MOV PC, LR;子程序返回

注意:转移地址限制在当前指令的 ±32 MB 的范围内。BL 指令用于子程序调用。

Page 97: 嵌入式系统讲义 第 3 章   ARM 指令系统

例子:根据不同的条件,执行不同的子程序。 CMP R1, #5

BLLT ADD11 ;有符号数 < BLGE SUB22 ;有符号数 ≧

…ADD11 …SUB22

注:如果 R1<5 ,只有 ADD11 不改变条件码,本例才能正常工作。

Page 98: 嵌入式系统讲义 第 3 章   ARM 指令系统

例子: BL SUB1 ……SUB1 STMFD R13! ,{R0-R3,R14}

…… BL SUB2 ……SUB2 ……

注意:在保存 R14之前子程序不应再调用下一级的嵌套子程序。否则,新的返回地址将覆盖原来的返回地址,就无法返回到原来的调用位置。

Page 99: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 BX—— 带状态切换的转移指令

指令格式如下: BX{cond} Rm

BX 指令跳转到 Rm 指定的地址执行程序。• 若 Rm 的位 [0] 为 1 ,则跳转时自动将 CPSR 中

的标志 T 置位,即把目标地址的代码解释为 Thumb代码;

• 若 Rm 的位 [0] 为 0 ,则跳转时自动将 CPSR 中的标志 T复位,即把目标地址的代码解释为 ARM 代码。

Page 100: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令举例如下: ADRL R0 , ThumbFun+1

;中等范围的地址读取伪指令 BX R0 ;跳转到 R0 指定的地址,并

;根据 R0 的最低位来切换处理 ;器到 Thumb状态。

……..

ThumbFun

Page 101: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 BLX — 带链接和状态切换的转移指令

指令格式如下: BLX <target address> BLX 指令先将下一条指令的地址拷贝到 R14

( 即 LR)连接寄存器中,然后跳转到指定地址处执行程序。 ( 只有 V5T 及以上体系 支持 BLX)

转移地址限制在当前指令的 ±32MB 的范围内。

Page 102: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.4 协处理器指令 ARM 协处理器: ARM 支持 16 个协处理器,

用于各种协处理器操作,最常使用的协处理器是用于控制片上功能的系统协处理器,例如控制高速缓存和存储器的管理单元,浮点 ARM 协处理器等,还可以开发专用的协处理器。

ARM 协处理器指令根据其用途主要分为以下三类:

协处理器数据操作指令。ARM 寄存器与协处理器寄存器的数据传送指

令。协处理器寄存器和内存单元之间数据存 /取指

令。

Page 103: 嵌入式系统讲义 第 3 章   ARM 指令系统

ARM 的协处理器指令功能:( 1 ) ARM 处理器初始化 ARM 协处理器的数据处理操作;( 2 )在 ARM 处理器的寄存器和协处理器的寄存器之间传送数据;( 3 )在 ARM 协处理器的寄存器和存储器之间传送数据。

ARM 协处理器指令包括以下 5 条: — CDP 协处理器数操作指令 coprocessor— LDC 协处理器数据加载指令 — STC 协处理器数据存储指令 — MCR ARM 处理器寄存器到协处理器寄存器

的数据传送指令— MRC 协处理器寄存器到 ARM 处理器寄存器

的数据传送指令

Page 104: 嵌入式系统讲义 第 3 章   ARM 指令系统

一、 CDP—— 协处理器数据操作指令 ARM 处理器通过 CDP 指令通知 ARM 协处理器执行特定

的操作。协处理器数据操作完全是协处理器内部的操作,用于初始化 ARM 协处理器,完成协处理器寄存器的状态改变。

指令格式如下:CDP{<cond>} <CP#> , <Cop1> , CRd , CRn , CRm {,<Co

p2>}

其中: • CP# 指令操作的协处理器名。标准名为 pn , n 为 0~ 15 。• Cop1 协处理器的特定操作码。• CRd 作为目标寄存器的协处理器寄存器。• CRn 存放第 1 个操作数的协处理器寄存器。• CRm 存放第 2 个操作数的协处理器寄存器。• Cop2 可选的协处理器特定操作码。

Page 105: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令举例如下:• CDP p7 , 0 , c0 , c2 , c3 , 0

;协处理器 7 执行操作码 1 为0 和 ;可选操作码 2 为 0 的操作。

• CDP p6 , 1 , c3 , c4 , c5 ;协处理器 6 执行;操作码为 1 的操

作 指令特点:

– 该操作由协处理器完成,即对命令参数的解释与协处理器有关,指令的使用取决于协处理器。

– 若协处理器不能成功地执行该操作,将产生未定义指令异常中断。

Page 106: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、 LDC/STC—— 协处理器数据取 / 存指令 协处理器数据取 / 存指令从存储器读取数据装入

协处理器寄存器,或将协处理器寄存器的数据存入存储器。1 、 LDC—— 协处理器数据读取指令

LDC 指令从某一连续的内存单元将数据读取到协处理器的寄存器中。进行协处理器的数据传送时,由协处理器来控制传送的字数。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。

Page 107: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令格式如下: LDC{cond}{L} <CP#> , CRd , <地址 >

其中:• L 可选后缀,指明是长整数传送。• CP# 指令操作的协处理器名。标准名为 pn , n 为 0~15 。• CRd 作为目标寄存的协处理器寄存器。 <地址 > 指定的内存地址。

指令举例如下:• LDC p5 , c2 , [R2 , #4] ;读取 R2+4 指向的内

存单元的数据,传送到协处理器 p5 的 c2 寄存器中。• LDC p6 , c2 , [R1] ;读取 R1 指向的内

存单元的数据,传送到协处理器 p6 的 c2 寄存器中。

Page 108: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 STC—— 协处理器数据存入指令 将协处理器的寄存器数据存入到某一连续的内存单元中,由协处理器来控制写入的字数。 若协处理器不能成功地执行该操作,将产生未定义指令异常中断。

指令格式如下:STC{cond}{L} CP# , CRd , <地址 >

其中格式说明同 LDC 指令。指令举例如下:

• STC p5 , c1 , [R0]• STC p5 , c1 , [R0 , #0x04]

Page 109: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、 MCR/MRC——ARM 寄存器与协处理器寄存器的数据传送指令

1 、 MCR ——ARM 寄存器到协处理器寄存器的数据传送指令

MCR 指令将 ARM 处理器的寄存器中的数据传送到协处理器的寄存器中。 若协处理器不能成功地执行该操作,将产生未定义指令异常中断。

指令格式如下:MCR{cond} CP# , Cop1, Rd, CRn, CRm{, <Cop2>}

其中格式说明同 CDP 指令。指令举例如下:

MCR p14 , 3 , R7 , c7 , c11 , 6 ;从 ARM 寄存器中将数据传送到协处理器 p14 的寄存器

;中,其中 R7 为 ARM 寄存器,存放源操作数; c7 和 c11 为;协处理器寄存器,是目标寄存器;操作码 1 为 3;操

作码 2 为 6 。

Page 110: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 MRC—— 协处理器寄存器到 ARM 寄存器的数据传送指令

MRC 指令将协处理器寄存器中的数据传送到 ARM 处理器的寄存器中。若协处理器不能成功地执行该操作,将产生未定义指令异常中断。

指令格式如下: MRC{cond} CP# , Cop1, Rd , CRn , CRm{, <Cop2>}其中格式说明同 CDP 指令。

指令举例如下:MRC p5 , 2 , R2 , c3 , c2

Page 111: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.5 杂项指令 主要由两种类型指令组成,程序状态寄存器操作

指令、中断操作指令,一共有 5 条指令。状态寄存器操作指令:

MRS :读程序状态寄存器指令 MSR :写程序状态寄存器指令

异常中断操作指令: SWI : 软件中断指令 BKPT :断点指令( v5T体系) CLZ : 前导 0 计数( v5T体系)

Page 112: 嵌入式系统讲义 第 3 章   ARM 指令系统

一、程序状态寄存器处理指令 ARM 指令中有两条指令,用于在状态寄存器和通

用寄存器之间传送数据。修改状态寄存器一般是通过“读取-修改-写回”三个步骤的操作来实现的。

1 、 MRS——读状态寄存器指令 指令格式如下:

MRS{cond} Rd , psr ; Rd psr 把状态寄存器 psr ( CPSR 或 SPSR )的内容

传送到目标寄存器中。其中: Rd —— 目标寄存器。 Rd 不允许为 R15 。 psr —— CPSR 或 SPSR 。 注意:在 ARM 处理器中,只有 MRS 指令可以将状态寄存器 CPSR 或 SPSR读出到通用寄存器中。

Page 113: 嵌入式系统讲义 第 3 章   ARM 指令系统

ARM状态寄存器的格式

1 、条件码标志位(保存 ALU 中的当前操作信息)N :正负号 / 大小 标志位

0 表示:正数 / 大于; 1 表示:负数 / 小于Z :零标志位

0 表示:结果不为零; 1 表示:结果为零C :进位 /借位 /移出位

0 表示:未进位 /借位 /移出 0; 1 表示:进位 /未借位 /移出 1

V :溢出标志位0 表示:结果未溢出; 1 表示:结果溢出

Q : DSP 指令溢出标志位(用于 v5 以上 E 系列) 0 表示:结果未溢出; 1 表示:结果溢出

31 30 29 28 27 26…8 7 6 5 4 3 2 1 0

N Z C V Q ( 保留 ) I F T M4 M3 M2 M1 M0

Page 114: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令举例如下:MRS R1 , CPSR ; R1 CPSR

MRS R2 , SPSR ; R2 SPSR

MRS与MSR 指令的应用目的:• 获得 CPSR 或 SPSR 的状态:

– 用 MRS 指令读取 CPSR ,可用来判断 ALU 的状态标志,或 IRQ 、 FIQ 中断是否允许等。

– 用 MRS 指令在异常处理程序中,读 SPSR 可知道进行异常前的处理器状态等。

• CPSR 或 SPSR 进行修改: MRS与 MSR配合使用,实现 CPSR 或 SPSR 寄存器的读—修改—写操作,可用来进行处理器模式切换、允许/禁止 IRQ/FIQ 中断等设置。

Page 115: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 MSR—— 写状态寄存器指令 在 ARM 处理器中,只有 MSR 指令可以直接设置状态寄存器 CPSR 或 SPSR 。

指令格式如下:MSR{cond} psr_fields , #immed

MSR{cond} psr_fields , Rm

其中: • psr : CPSR 或 SPSR 。• immed : 要传送到状态寄存器指定域的 8 位立即数。• Rm : 要传送到状态寄存器指定域的数据的源寄 存器。

Page 116: 嵌入式系统讲义 第 3 章   ARM 指令系统

• fields 指定传送的区域。 fields 可以是以下的一种或多种 ( 字母必须为小写 ) :– c 控制域 (psr[7…0]);– x 扩展域 (psr[15…8]); (暂未用 )

– s 状态域 (psr[23…16]); (暂未用 )

– f 标志位域 (psr[31…24]) 。程序状态寄存器分域图

15 8 7 0

保留 I F T mode

x (扩展域) c (控制域)

31 24 23 16

N Z C V Q 保留 保留f (标志位域) s (状态域)

Page 117: 嵌入式系统讲义 第 3 章   ARM 指令系统

指令举例如下:MSR CPSR_f , #0xf0 ; CPSR[31:28] = 0xf(0b1111)

;即 N,Z,C,V均被置 1 。修改状态寄存器一般是通过“读取-修改-写回”三

个步骤的操作来实现的。

CPSR 的读—修改—写操作举例如下:• 例 1 :设置进位位 CMRS R0, CPSR ;R0CPSRORR R0,R0,#0x20000000 ; 置 1 进位位 CMSR CPSR_f, R0 ;CPSR_fR0[31:24]

• 例 2 :从管理模式切换到 IRQ模式MRS R0, CPSR ;R0CPSRBIC R0,R0,#0x1f ;低 5 位清零ORR R0,R0,#0x12 ; 设置为 IRQ模式MSR CPSR_c, R0 ;传送回 CPSR

Page 118: 嵌入式系统讲义 第 3 章   ARM 指令系统

注 意: 控制域的修改问题:只有在特权模式下才能修改状态寄存器的控制域 [7 : 0] ,以实现处理器模式转换,或设置开 /关异常中断 。 T控制位的修改问题:程序中不能通过 MSR 指令,直接修改 CPSR 中的 T控制位来实现 ARM状态/ Thumb状态的切换,必须使用 BX 指令完成处理器状态的切换。 用户模式下能够修改的位:在用户模式只能修改“标志位域”,不能对 CPSR[23 : 0]做修改。 S 后缀的使用问题:在 MRS/MSR 指令中不可以使用 S 后缀。

Page 119: 嵌入式系统讲义 第 3 章   ARM 指令系统

例:堆栈初始化INITSTACK ;堆栈初始化子程序

MOV R0 , LR ;保存返回地址MRS R1 , CPSR ;保存 CPSR原值MSR CPSR_c , #0xD3 ;切换到管理模式

…… ;设置堆栈大小等LDR SP , StackSvc ;设置堆栈指针

MSR CPSR_c , #0xD2 ;切换到中断模式…… ;设置堆栈大小等

LDR SP , StackIrq ;设置堆栈指针

…… ;对其它模式设置MSR CPSR_c , R1 ;恢复 CPU原

模式 MOV PC , R0 ;子程序返回

第 7次到此

Page 120: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、异常中断产生指令

异常中断指令可以分为以下几种: SWI : 软件中断指令 BKPT :断点指令( v5T 及以上体系) CLZ : 前导 0 计数( v5T 及以上体系)

Page 121: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、 SWI——软件中断指令 软件中断指令 SWI产生软件异常中断,用来实现用户模式到特权模式的切换。用于在用户模式下对操作系统中特权模式的程序的调用;它将处理器置于管理( _svc )模式,中断矢量地址为 0x08 。

指令格式如下: SWI {<cond>} <24 位立即数 >

说明:– 主要用于用户程序调用操作系统的 API 。– 参数传递通常有两种方法:

• 指令中的 24bit 立即数指定 API 号,其它参数通过寄存器传递。

• 忽略指令中的 24bit 立即数, r0 指定 API 号,其它参数通过其它寄存器传递。

Page 122: 嵌入式系统讲义 第 3 章   ARM 指令系统

SWI 指令举例:• 软中断号在指令中,不传递其它参数

SWI 10 ;中断号为 10

SWI 0x123456 ;中断号为 0x123456

• 软中断号在指令中,其它参数在寄存器中传递MOV R0 , #34 ;准备参数SWI 12 ;调用 12 号软中断

• 不用指令中的立即数,软中断号和其它参数都在寄存器中传递MOV R0 , #12 ;准备中断号MOV R1 , #34 ;准备参数SWI 0 ;进入软中断

Page 123: 嵌入式系统讲义 第 3 章   ARM 指令系统

SWI 程序举例:T_bit EQU 0x20 ;用于测试 Thumb 标志位 ( 第 5

位 )

SWI_handler

STMFD SP!, {R0-R3 , R12 , LR}

MRS R0 , SPSR ;保存中断前的 CPSR 值STMFD SP!, {R0} ;到堆栈中TST R0 , #T_bit ;测试 T 位标志LDRNEH R0 , [LR , # -2] ;读取 16 位的 SWI 指令码BICNE R0 , R0 , #0xFF00 ;获取 SWI 中的中

断号LDREQ R0 , [LR , # -4] ;读取 32 的 SWI 指令码BICEQ R0 , R0 , #0xFF000000;获取 SWI 中的中断号

…… ;转去处理相应的软中断LDMFD SP!, {R0-R3 , R12 , PC}

;中断返回,包括恢复原 CPSR 值

Page 124: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 BKPT——断点指令

断点中断指令 BKPT 用于产生软件断点,供调试程序用。 v5T 及以上体系使用。

指令格式如下: BKPT { immed_16}

immed_16 : 16 位的立即数。该立即数被调试软件用来保存额外的断点信息。

断点指令用于软件调试;它使处理器停止执行正常指令而进入相应的调试程序。

Page 125: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 CLZ—— 前导 0 计数指令

前导 0 计数指令 CLZ 对 Rm 中的前导 0 的个数进行计数,结果放到 Rd 中。 v5T 及以上体系使用。

指令格式: CLZ{<cond>} Rd, Rm

举例如下: MOV R2 , #0X17C00

; R2=0b0000 0000 0000 0001 0111 1100 0000 0000

CLZ R3 , R2 ; R3=15

Page 126: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.3.6 例 题

一、算数逻辑运算指令的应用

• 例 1 : 实现乘法的指令段

MOV R0,R0,LSL #n ;R0=R0<<n; R0= R0*2n

ADD R0,R0,R0,LSL #n ;R0=R0+R0*2n= R0*(2n+1)

RSB R0,R0,R0,LSL #n ;R0=R0*2n-R0= R0*(2n-1)

Page 127: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 2 : 64 位数据运算假设 R0 和 R1 存放一个 64 位数据, R0 中存放数

据的低 32 位; R2 和 R3 中存放另一个 64 位数据, R2中存放数据的低 32 位。对这两个 64 位数进行加、减和比较运算。( R1 , R0 )、( R3 , R2 )

①两个 64 位数据的加法运算,结果保存到 R0 和R1 中。

ADDS R0,R0,R2 ;低 32 位相加,设置 CPSR 的 C 标志位。

ADC R1,R1,R3 ; 高 32 位的带位相加

Page 128: 嵌入式系统讲义 第 3 章   ARM 指令系统

②两个 64 位数据的减法运算,结果保存到 R0和 R1 中。

SUBS R0,R0,R2 ;低 32 位相减,设置 CPSR 的 C 标志位。 SBC R1,R1,R3 ; 高 32 位的带位相减

③两个 64 位数据的比较操作,并设置 CPSR 中的条件标志位。

CMP R1,R3 ;比较高 32 位 CMPEQ R0,R2 ; 如果高 32 位相等,比较低 32 位

Page 129: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 3 :转换内存中数据存储方式

将寄存器 R0 中的数据存储方式转换成另一种存储方式。指令执行前 R0 中数据存储方式为: R0=A,B,C,D;指令执行后 R0 中数据存储方式为: R0=D,C,B,A 。

EOR R1,R0,R0, ROR #16 ;R1=A^C,B^D,C^A,D^B

BIC R1,R1,#OxFF0000 ;R1=A^C,0,C^A,D^B

MOV R0,R0,ROR #8 ;R0=D,A,B,C

EOR RO,RO,R1,LSR #8 ;R0=D,C,B,A

;R0=D,A,B,C异或 R1=0,A^C,0,C^A

Page 130: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、跳转指令的应用• 例 1 :子程序的调用 BL 指令在执行跳转操作的同时保存下一条指

令的地址,用于从被调用的子程序中返回。 …… BL function ;调用子程序 function …… ;子程序结束后,程序将返回到这里执行 ……function ;子程序的程序体 ……

MOV PC,LR ;子程序中的返回语句

Page 131: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 2 :条件执行实现类似于 C 语言中的 if-else功能的代码

段。下例的功能为求最大公约数。• 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;代码执行后 R0 中存放最大公约数。

gcd

CMP R0,R1 ;比较 a 和 b 的大小

SUBGT R0,R0,R1 ;if(a>b) a=a-b

SUBLT R1,R1,R0 ;if(b>a) b=b-a

BNE gcd ;if(a!=b)跳转到 gcd继续执行

MOV PC,LR ;子程序结束,返回

Page 132: 嵌入式系统讲义 第 3 章   ARM 指令系统

循环结构

MOV R1,#10

LOOP …… ;循环体SUB R1,R1,#1

BNE LOOP

……

Page 133: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 3 :循环语句将内存中从 0x400800开始的 100 个字数据相加,

其结果存于 R3 、 R2 中( R3 中为高 32 位)。LDR R0 , =0x400800

MOV R1 , #100 ;初始化循环次数MOV R2 , #0MOV R3 , #0

loop ;循环体LDR R4 , [R0] , #4

ADDS R2 , R2 , R4ADC R3 , R3 , #0 或者 ADDCS R3 , R3 ,

#1 SUBS R1 , R1 , #1 ;循环计数器减 1 ,设置条

件标志 BNE loop ;循环计数器不为 0,跳到 loop继续执行 …… ;循环计数器为 0 ,程序继续执行

Page 134: 嵌入式系统讲义 第 3 章   ARM 指令系统

例 4 :链表操作中的条件码应用

在链表中搜索与某一数据相等的元素。链表的每个元素包括两个字,第 1 个字中包含

一个字节数据;第 2 个字中包含指向下一个链表元素的指针,当这个指针为 0 时表示链表结束。

代码执行前 R0 指向链表的头元素, R1 中存放将要搜索的数据;代码执行后 R0 指向第 1 个匹配的元素,或者当没有匹配元素时, R0 为 0 。

SEARCH CMP R0,#0 ;R0 指针是否为空 LDRNEB R2,[R0] ;读取当前元素中的字节数据 CMPNE R1,R2 ;判断数据是否为搜索的数据 LDRNE R0,[R0,#4] ; 如果不是 , 指针 R0 指向下一个元素

BNE SEARCH ;跳转到 search 执行 MOV PC,LR ;搜索完成,程序返回

Page 135: 嵌入式系统讲义 第 3 章   ARM 指令系统

SEARCH

CMP R0,#0 ;R0 指针是否为空 LDRNEB R2,[R0] ;读取当前元素中的字节数

据 CMPNE R1,R2 ;判断数据是否为搜索的数据 LDRNE R0,[R0,#4] ; 如果不是 , 指针 R0 指向下

一 ;个元素

BNE SEARCH ;跳转到 search 执行 MOV PC,LR ;搜索完成,程序返回

Page 136: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.4 Thumb 指令集

(在本章最后)

Page 137: 嵌入式系统讲义 第 3 章   ARM 指令系统

主要内容3.5.1 概念3.5.2 ARM 汇编伪指令3.5.3 ARM 汇编伪操作

一、符号定义伪操作 二、 数据定义伪操作 三、汇编控制伪操作 四、其他伪操作

3.5.4 ARM 汇编宏指令ADS 编译环境下的伪操作

3.5 ARM 汇编伪指令和伪操作

Page 138: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.5.1 伪指令、伪操作和宏指令概念• 伪指令——是汇编语言程序里的特殊指令助记符,

在汇编时被合适的机器指令替代。• 伪操作——为汇编程序所用,在源程序进行汇编

时由汇编程序处理,只在汇编过程起作用,不参与程序运行。

• 宏指令——通过伪操作定义的一段独立的代码。在调用它时将宏体插入到源程序中。也就是常说的宏。

说明:所有的伪指令、伪操作和宏指令,均与具体的开发工具中的编译器有关,当前主要采用ARM公司的“ ADS/SDT IDE”开发工具,所以后面的讨论,均是基于 ARM公司的开发工具。

Page 139: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.5.2 ARM 汇编伪指令

ARM 伪指令不属于 ARM 指令集中的指令,是为了编程方便而定义的。伪指令可以像其它 ARM 指令一样使用,但在编译时这些指令将被等效的 ARM 指令代替。 ARM 伪指令有四条,分别是:– ADR :小范围的地址读取伪指令。– ADRL :中等范围的地址读取伪指令。– LDR :大范围的地址读取伪指令。– NOP :空操作伪指令。

Page 140: 嵌入式系统讲义 第 3 章   ARM 指令系统

一、 ADR—— 小范围的地址读取ADR 伪指令功能:将基于 PC 相对偏移的地址

值或基于寄存器相对偏移的地址值读取到寄存器中。 ADR 伪指令功能的实现方法:在汇编编译器

编译源程序时, ADR 伪指令被编译器替换成一条合适的指令。通常,编译器用一条 ADD 指令或 SUB 指令来实现此 ADR 伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

语法格式: ADR{cond} register , expr其中:

– register :加载的目标寄存器。– expr :地址表达式。取值范围是参考 P212

Page 141: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 1 : ……

(0x20) ADR R1,Delay

……

Delay

(0x64) MOV R0,R14

……

使用 ADR将程序标号 Delay 所表示的地址存入 R1 。

编译后的反汇编代码:

……

ADD R1,PC,#0x3C

……

MOV R0,R14

PC+0x3C=0x20+0x08+0x3C=0x64

Page 142: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 2 :查表 ADR R0,D_TAB ; 加载转换表地址 LDRB R1,[R0,R2] ;使用 R2 作为参数,进行查

表 ……

D_TAB

DCB 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92

Page 143: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、 ADRL—— 中等范围的地址读取

ADRL 伪指令功能:将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比 ADR 伪指令可以读取更大范围的地址。

ADRL 伪指令功能实现方法:在汇编编译器编译源程序时, ADRL 被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。

语法格式: ADRL{cond} register,expr

其中:– register :加载的目标寄存器。– expr :地址表达式。取值范围参考 P212

Page 144: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 3 : ……

(0x20) ADRL R1,Delay

……

Delay

(0x64) MOV R0,R14

……

使用 ADRL将程序标号Delay 所表示的地址存入 R1 。

编译后的反汇编代码:

……

ADD R1,PC,#0x3C

ADD R1,R1,#0

……

MOV R0,R14

ADRL 伪指令被汇编成两条指令,尽管第 2 条指令并没有意义。

Page 145: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、 LDR —— 大范围的地址读取LDR 伪指令功能:用于加载 32 位立即数或一

个地址值到指定的寄存器。LDR 伪指令功能实现方法:在汇编编译源程

序时, LDR 伪指令被编译器替换成一条合适的指令。– 若加载的常数未超过 MOV 或 MVN 的范围,则使

用 MOV 或 MVN 指令代替该 LDR 伪指令;– 否则汇编器将常量放入文字池,并使用一条程序相

对偏移的 LDR 指令从文字池读出常量。语法格式:

LDR{cond} register,=expr其中:

– Register :加载的目标寄存器。– expr : 32 位常量或地址表达式。

Page 146: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例 4 : ……

(0x060) LDR R1,=Delay

……

Delay

(0x102) MOV R0,R14

……

使用 LDR将程序标号Delay 所表示的地址存入R1 。

编译后的反汇编代码: ……

LDR R1,stack ……Delay

MOV R0,R14

……

LTORG

stack DCD 0x102

LDR 伪指令被汇编成一条 LDR指令 ,并在文字池中定义一个常量 ,该常量为标号 Delay 的地址。

Page 147: 嵌入式系统讲义 第 3 章   ARM 指令系统

注意:• 从指令位置到文字池的偏移量必须小于 4K

B 。• 与 ARM 指令的 LDR 的区别:伪指令 LD

R 的参数有“ =” 号。

Page 148: 嵌入式系统讲义 第 3 章   ARM 指令系统

四、 NOP——空操作伪指令

NOP 伪指令功能实现方法:在汇编时将被替代成 ARM 中的空操作,比如可能是“MOV R0,R0” 指令等。

用途: NOP 可用于延时操作。语法格式: NOP

例:延时子程序 Delay NOP ;空操作 NOP NOP SUBS R1,R1,#1 ;循环次数减 1 BNE Delay MOV PC,LR

第 8次到此

Page 149: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.5.3 ARM 汇编伪操作

ADS 编译环境下的伪操作可分为以下几类:符号定义( Symbol Definition )伪操作 数据定义( Data Definition )伪操作 汇编控制( Assembly Control )伪操作 其它( Miscellaneous )伪操作

Page 150: 嵌入式系统讲义 第 3 章   ARM 指令系统

一、符号定义伪操作

GBLA , GBLL , GBLS :声明全局变量。LCLA , LCLL , LCLS :声明局部变量。SETA , SETL , SETS :给变量赋值。RLIST :为通用寄存器列表定义名称。

Test3 SETA 0xaa ;将该变量赋值为 0xaa

Page 151: 嵌入式系统讲义 第 3 章   ARM 指令系统

二、数据定义伪操作• LTORG :声明一个数据缓冲池的开始• SPACE :分配一块字节内存单元,并用 0初始化• DCB :分配一段字节内存单元,并初始化• DCD 、 DCDU :分配一段字内存单元,并初始化• MAP :定义一个结构化的内存表的首地址• FIELD :定义结构化内存表中的一个数据域

MAP 0x100 , R0 ;定义结构化内存表首地址的值为 0x100 + R0A FIELD 16 ;定义 A 的长度为 16 字节,位置为 0x110+R0

LTORG ; 定义数据缓冲池 &0x8000Data SPACE 4200 ; 从当前位置开始分配 4200 字节的内存单元,

; 并初始化为 0 。

Page 152: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、 LTORG

用于声明一个数据缓冲池(文字池)的开始。语法格式:

LTORG• 例: start BL func ;( 146页) …… func LDR R1,=0x8000 ;子程序 …… MOV PC,LR ;子程序返回 LTORG ; 定义数据缓冲池&0x8000Data SPACE 4200 ;从当前位置开始分配 4200 字节的内 存单元,并初始化为 0 。 END 默认数据缓冲池为空

Page 153: 嵌入式系统讲义 第 3 章   ARM 指令系统

注意:• LTORG 伪操作通常放在无条件跳转指令之后,

或者子程序返回指令之后,这样处理器不会错误地将数据缓冲池中的数据当作指令来执行。

• 通常 ARM 汇编编译器把数据缓冲池放在代码段的最后面,即下一个代码段开始之前,或者 END伪操作之前。

Page 154: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 DCB—— 也可以用符号” =” 表示

用于定义并且初始化一个或者多个字节的内存区域。

语法格式: {label} DCB expr{,expr}……

或 {label} = expr{,expr}

其中 expr 表示:– -128到 255之间的一个数值常量或者表达式。– 一个字符串。

注意:当 DCB 后面紧跟一个指令时,可能需要使用 ALIGN确保指令是字对齐的。

Page 155: 嵌入式系统讲义 第 3 章   ARM 指令系统

例:short DCB 1 ; 为 short 分配了一个

; 字节 ,并初始化为 1 。

string DCB “string”,0 ; 构造一个以 0

; 结尾的字符串

Page 156: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 DCD 、 DCDU 分配一段字内存单元( 1 ) DCD —— 分配一段字对齐的内存单元用于分配一段字对齐的内存单元,并初始化。

DCD 也可以用符号”&” 表示语法格式:

{label} DCD expr{,expr}……

或 {label} & expr{,expr}…… expression

其中:expr :数字表达式或程序中的标号。

注意: DCD 伪操作可能在分配的第一个内存单元前插入填补字节以保证分配的内存是字对齐的。

Page 157: 嵌入式系统讲义 第 3 章   ARM 指令系统

例:data1 DCD 2,4,6

; 为 data1 分配三个字 , 内容初始化为2,4,6

data2 DCD label+4 ;初始化 data2 为 label+4 对应的地址

( 2 ) DCDU —— 分配一段字非严格对齐的内存单元

DCDU与 DCD 的不同之处在于 DCDU 分配的内存单元并不严格字对齐。

Page 158: 嵌入式系统讲义 第 3 章   ARM 指令系统

三、汇编控制伪操作

• IF,ELSE 及 ENDIF :有条件选择汇编• WHILE 及 WEND :有条件循环(重复)汇

编• MACRO,MEND 及 MEXIT :宏定义汇编

Page 159: 嵌入式系统讲义 第 3 章   ARM 指令系统

四、其它伪操作1 、 AREA :定义一个代码段或数据段2 、 CODE16 、 CODE32 :告诉编译器后面的指令序列位数3 、 ENTRY :指定程序的入口点4 、 ALIGN :将当前的位置以某种形式对齐 ALIGN 或5 、 END :源程序结尾 ALIGN n :以字或 n 字节对齐6 、 EQU :为数字常量、基于寄存器的值和程序中的标号定义一

个字符名称。7 、 EXPORT 、 GLOBAL :声明源文件中的符号可以被其他源

文件引用8 、 IMPORT 、 EXTERN :声明某符号是在其他源文件中定义的9 、 GET 、 INCLUDE :将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。

10 、 INCBIN :将一个文件包含到当前源文件中,而被包含的文件不进行汇编处理

Page 160: 嵌入式系统讲义 第 3 章   ARM 指令系统

1 、 AREA用于定义一个代码段或是数据段。语法格式:

AREA sectionname{,attr} {,attr}…attribute

其中:– sectionname :为所定义的段的名称。– attr :该段的属性。具有的属性为:

• CODE :定义代码段。• DATA :定义数据段。• READONLY :指定本段为只读 , 代码段的默认属性。• READWRITE :指定本段为可读可写 , 数据段的默认属性。

Page 161: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ALIGN :指定段的对齐方式为 2expression 。 expression 的取值为 0~31 。

• COMMON :指定一个通用段。该段不包含任何用户代码和数据。

• NOINIT :指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个内存单元值初始化为 0 。

注意:一个大的程序可包含多个代码段和数据段。一个汇编程序至少包含一个代码段。

Page 162: 嵌入式系统讲义 第 3 章   ARM 指令系统

2 、 CODE16 和 CODE32

CODE16告诉汇编编译器后面的指令序列为 16 位的 Thumb 指令。

CODE32告诉汇编编译器后面的指令序列为 32 位的 ARM 指令。

语法格式: CODE16

CODE32

注意: CODE16 和 CODE32 只是告诉编译器后面指令的类型,该伪操作本身不进行程序状态的切换。

Page 163: 嵌入式系统讲义 第 3 章   ARM 指令系统

例:AREA ChangeState, CODE, READONLY

ENTRY

CODE32 ; 下面为 32 位 ARM 指令 LDR R0,=start+1

BX R0

……

CODE16 ; 下面为 16 位 Thumb 指令start MOV R1,#10

…….

END

;切换到 Thumb状态,并跳转到 start 处执行

Page 164: 嵌入式系统讲义 第 3 章   ARM 指令系统

3 、 ENTRY

指定程序的入口点。语法格式:

ENTRY

注意: 一个程序(可包含多个源文件)中至少

要有一个 ENTRY (可以有多个 ENTRY ),但一个源文件中最多只能有一个 ENTRY(可以没有 ENTRY )

Page 165: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 、 ALIGN

ALIGN 伪操作通过填充 0将当前的位置以某种形式对齐。

语法格式:ALIGN {expr{,offset}}

其中:– expr :一个数字,表示对齐的单位。这个数字是 2 的整

数次幂,范围在 20~231之间。 如果没有指定 expr ,则当前位置对齐到下一

个字边界处。– Offset :偏移量,可以为常数或数值表达式。不指定 offs

et 表示将当前位置对齐到以 expr 为单位的起始位置。

Page 166: 嵌入式系统讲义 第 3 章   ARM 指令系统

例 1 :short DCB 1 ; 本操作使字对齐被破坏ALIGN ;重新使其为字对齐MOV R0,1

例 2 :ALIGN 8 ; 当前位置以 2 个字的方式

对齐

Page 167: 嵌入式系统讲义 第 3 章   ARM 指令系统

5 、 END

END 伪操作告诉编译器已经到了源程序结尾。

语法格式: END

注意:   每一个汇编源程序都必须包含 END

伪操作,以表明本源程序的结束。

Page 168: 嵌入式系统讲义 第 3 章   ARM 指令系统

6 、 EQU —— 也可以用符号” *” 表示

EQU 伪操作为数字常量、基于寄存器的值和程序中的标号定义一个字符名称。

语法格式: name EQU expr{ , type}其中:

– name :为 expr 定义的字符名称。– expr :基于寄存器的地址值、程序中的标号、 32 位的地

址常量或者 32 位的常量。表达式,为常量。– type :当 expr 为 32 位常量时,可以使用 type 指示 expr

的数据的类型。取值为:• CODE32

• CODE16

• DATA

Page 169: 嵌入式系统讲义 第 3 章   ARM 指令系统

例: abcd EQU 2 ; 定义 abcd 符号的值为 2

abcd EQU label+16 ; 定义 abcd 符号的值为 (label+16)

abcd EQU 0x1c,CODE32 ; 定义 abcd 符号的值为绝对地址 ; 值 0x1c ,而且此处为 ARM 指

Page 170: 嵌入式系统讲义 第 3 章   ARM 指令系统

7 、 EXPORT 及 GLOBAL

声明一个源文件中的符号,使此符号可以被其他源文件引用。

语法格式:EXPORT/GLOBAL symbol {[weak]}

其中:– symbol :声明的符号的名称。(区分大小写)– [weak] :声明其他同名符号优先于本符号被引用。

例: AREA example , CODE , READONLY EXPORT DoAdd DoAdd ADD R0 , R0 , R1

Page 171: 嵌入式系统讲义 第 3 章   ARM 指令系统

8 、 IMPORT 及 EXTERN

声明一个符号是在其他源文件中定义的。语法格式:IMPORT symbol{[weak]}

EXTERN symbol{[weak]}

其中:– symbol :声明的符号的名称。

Page 172: 嵌入式系统讲义 第 3 章   ARM 指令系统

– [weak] :• 当没有指定此项时,如果 symbol 在所有的源文件

中都没有被定义,则连接器会报告错误。• 当指定此项时,如果 symbol 在所有的源文件中都

没有被定义,则连接器不会报告错误,而是进行下面的操作。

– 如果该符号被 B 或者 BL 指令引用,则该符号被设置成下一条指令的地址,该 B 或 BL 指令相当于一条 NOP 指令。

– 其他情况下此符号被设置成 0 。

Page 173: 嵌入式系统讲义 第 3 章   ARM 指令系统

9 、 GET 及 INCLUDE

将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。

指令格式:GET filename

INCLUDE filename

其中 : – filename: 包含的源文件名,可以使用路径信息(可包含空格)。

例: GET d:\arm\file.s

Page 174: 嵌入式系统讲义 第 3 章   ARM 指令系统

10 、 INCBIN

将一个文件包含到当前源文件中,而被包含的文件不进行汇编处理

指令格式:INCBIN filename

其中:– filename :被包含的文件名称,可使用路径信息(不能有空格)。适用情况:通常使用此伪操作将一个可执行文

件或者任意数据包含到当前文件中。例: INCBIN d:\arm\file.txt

Page 175: 嵌入式系统讲义 第 3 章   ARM 指令系统

例:编写一具有完整汇编格式的程序,实现冒泡法排序功能。设无符号字数据存放在从 0x400004开始的区域,字数据的数目字存放在 0x400000 中。

AREA SORT , CODE , READONLYENTRY

STARTMOV R1 , #0x400000

LPSUBS R1 , R1 , #1BEQ EXITMOV R7 , R1LDR R0 , =0x400004

LP1LDR R2 , [R0] , #4LDR R3 , [R0]CMP R2 , R3

STRLO R3 , [R0, # -4]

STRLO R2 , [R0]SUBS R7 , R7 , #1BNE LP1B LP

EXITEND

Page 176: 嵌入式系统讲义 第 3 章   ARM 指令系统

ARM 汇编中的文件格式

源程序文件 文件名 说 明

汇编程序文件 *.S 用 ARM 汇编语言编写的 ARM 程序或 Thumb 程序。

C 程序文件 *.C 用 C 语言编写的程序代码。

头文件 *.H为了简化源程序,把程序中常用到的常量命名、宏定义、数据结构定义等等单独放在一个文件中,一般称为头文件。

Page 177: 嵌入式系统讲义 第 3 章   ARM 指令系统

ARM 汇编与 C 的混合编程

内嵌汇编语法:

_asm

{指令 [; 指令 ] /*注释 */

[; 指令 ]

}

_inline void enable_IRQ(viod){

int tmp;_asm{

MRS tmp,CPSRBIC tmp,tmp,#0x80MSR CPSR_c,tmp

}}

Page 178: 嵌入式系统讲义 第 3 章   ARM 指令系统

习 题1 ARM 指令中的第二操作数“ operand2” 有哪些具体形式?

2 对于 ARM 的变址寻址方式,有基地址和偏移地址两部分组成。( 1 )基地址可以是哪些寄存器?( 2 )偏移地址可以有哪些形式?( 3 )总地址的计算方法有哪些?怎么表示?( 4 )变址寻址应用于哪些指令?

3 存储器从 0x400000开始的 100 个单元中存放着 ASCII 码,编写程序,将其所有的小写字母转换成大写字母,对其它的 ASCII 码不做变换。

Page 179: 嵌入式系统讲义 第 3 章   ARM 指令系统

4 编写程序,比较存储器中 0x400000 和 0x400004两无符号字数据的大小,并且将比较结果存于0x4008 的字中,若两数相等其结果记为 0 ,若前者大于后者其结果记为 1 ,若前者小于后者其结果记为 -1 。

5 将存储器中 0x400000开始的 200 字节的数据,传送到 0x400800开始的区域。

6 编写一程序,查找存储器从 0x400000开始的100 个字中为 0 的数目,将其结果存到 0x400190中。

7 编写一程序,存储器中从 0x400200开始有一个 64 位数。( 1 )将取反,再存回原处;( 2 )求其补码,存放到 0x400208 处 。

Page 180: 嵌入式系统讲义 第 3 章   ARM 指令系统

8 编写一简单 ARM 汇编程序段,实现 1+2+…+100 的运算。

9 编写一具有完整汇编格式的程序,实现 32 位二进制数转换成 11 位压缩的 BCD 码的十进制数。

设原数据存放在从 0x400000 处,转换后存放在 0x400004开始的地方。

10 假定有一个 25 字的数组,编译器分别用 R0 、 R1分配变量 x 和 y ,若数组的基地址放在 R2 中,使用后变址形式翻译: x=array[5]+y 。

11 使用汇编完成系列 C 的数组赋值:For(i=0;i<=10;i++)

a[i]=b[j]+c;

作 业:1 、 2 、 3 、 4 、 7 、 8

Page 181: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 182: 嵌入式系统讲义 第 3 章   ARM 指令系统

3.4 Thumb 指令集• (一) Thumb 指令集特点

– Thumb 指令集是 ARM 指令集压缩形式的子集,所有 Thumb 指令均有对应的 ARM 指令。

– 采用 16 位二进制编码,代码密度小。– 执行 Thumb 指令时,先动态解压缩,然后作为标准

的 ARM 指令执行。– 如何区分指令流取决于 CPSR 的第 5 位(位 T )。– 大多数 Thumb 数据处理指令采用 2 个操作数格式。– 由于 16 位的限制,移位操作变成单独指令。

Page 183: 嵌入式系统讲义 第 3 章   ARM 指令系统

– Thumb 指令集没有协处理器指令、单寄存器交换指令、乘加指令、 64 位乘法指令以及程序状态寄存器处理指令,而且指令的第 2 操作数受到限制。

– 除了分支指令 B 有条件执行功能外,其他指令均为无条件执行。

– Thumb 是一个不完整的体系结构,不能指望处理器只执行 Thumb 代码而不支持 ARM 指令集。

Page 184: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (二)状态切换• 1 、 ARM 状态进入 Thumb 状态的方法

– 执行带状态切换的转移指令 BX 。若 BX 指令指定的寄存器的最低位为 1 ,则将 T 置位,并将程序计数器切换为寄存器其他位给出的地址。

• BX R0 ;若 R0 最低位为 1 ,则转入 Thumb 状态

Page 185: 嵌入式系统讲义 第 3 章   ARM 指令系统

– 异常返回也可以将微处理器从 ARM 状态转换为 Thumb 状态。通常这种指令用于返回到进入异常前所执行的指令流,而不是特地用于转换到 Thumb 模式。

• MOV PC , LR ;当返回地址保存在 LR 时• STMFD SP!,{<registers>,LR} ; 当返回地址保存在堆栈时 ,

…… ; 进入异常后将 R14 入栈, …… ; 假设异常前执行的是 Thumb 指令, PC 保存于 LR

中 LDMFD SP!,{<registers>,PC} ; 返回指令

Page 186: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 2 、 Thumb 状态进入 ARM 状态的方法– 执行 Thumb 指令中的交换转移 BX 指令可以显式

地返回到 ARM 指令流。– 利用异常进入 ARM 指令流。

Page 187: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (三) Thumb 指令寄存器的使用r0

r1

r2

r3

r4

r5

r6

r7

r8

r9

r10

r11

r12

SP ( r13)

LR ( r14)

PC ( r15)

Lo 寄存器

Hi 寄 存器

CPSR

有 阴 影 的 寄 存 器访问时受到限制

对低( Lo ) 8 个通用寄存器 R0~R7 具有全部访问权限,可以被任意指令访问。寄存器 R8~R12 的访问受到限制,这些寄存器只能通过 MOV 、 ADD 和 CMP 访问。对寄存器 R13~R15 进行扩展以作特殊应用。CPSR 间接访问 ( CMP 和数据处理指令影响)。SPSR 不能访问。CPSR 的条件标志位由算术和逻辑操作设置并控制条件转移。

Page 188: 嵌入式系统讲义 第 3 章   ARM 指令系统

• Thumb-ARM 相似处:– Load/Store 结构。– 支持 8 位字节、 16 位半字和 32 位字数据类型,

半字以两字节边界对准,字以 4 字节边界对准。• Thumb-ARM 差异处:

– 大多数 Thumb 指令是无条件执行的,所有 ARM指令都是条件执行的。

– 许多 Thumb 数据处理指令采用 2 个操作数格式(目的寄存器与一个源寄存器相同), ARM 数据处理指令大多采用 3 个操作数格式。如

ADD R0 , R1– 由于采用高密度编码, Thumb 指令格式没有 AR

M 指令格式规则。

Page 189: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (四) Thumb转移指令• Thumb 转移指令用于:

– 向后转移形成循环;– 条件结构向前转移;– 转向子程序;– 处理器从 Thumb 状态切换到 ARM 状态。

• 程序相对转移,特别是条件转移与在 ARM 状态下相比,在范围上有更多的限制,转向子程序只能是无条件转移。

• Thumb 转移指令包括: B ; BL ; BX ; BLX

Page 190: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ①B 指令——目标为 Thumb 代码• 格式 1 : B < 条件码 > <Label>

<Lable>: 程序相对偏移表达式,多为同一代码块中的地址标号。

编码结构: -256~+256

• 格式 2 : B <Label>编码结构: ±2KB

15 12 0

1 1 0 1

11 8

条 件 码 8位 偏 移 量

7

Thumb 指令集中唯一可以条件执行的指令。

15 11 0

1 1 1 0 0

10

11位 偏 移 量

Page 191: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ②BL 指令——目标为 Thumb 代码• 格式: BL <Label>

• 编码结构: ±4M

15 11 0

1 1 1 1

10

11位 偏 移 量

12

H

Why ±4M±4M ?

BL 指令实际上分为两条指令:※( H=0 ) LR< PC+ (偏移量左移 12 位后符号扩展至 32 位);※( H=1 ) PC< LR+ (偏移量左移 1 位); 同时把下一条指令的地址写入 LR 中。

Page 192: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ③BX 指令——目标为 Thumb 代码或 ARM 代码• 格式: BX Rm• 编码结构:

其中: Rm装有目的地址的 ARM 寄存器。 Rm 的位 [0] 不用于地址部分。

若 Rm 的位 [0]清零,则:

— 位 [1] 也必须清零;

— 指令清零 CPSR 中的标志 T ,目的地址的代码被解释为 ARM 代码。

若 Rm 的位 [0] 置 1 ,则:

—目标地址的代码仍为 Thumb 代码。

15 0

0 1 0 0 0 1 1 18

0 0 0

3

Rm5 267

0 H

Page 193: 嵌入式系统讲义 第 3 章   ARM 指令系统

• ④BLX 指令• 格式 1 : BLX <Label> —— 目标为 ARM 代

码15 11 0

1 1 1 1

10

10 位偏移量12

H 0

1

格式 2 : BLX Rm—— 目标为 ARM 代码或 Thumb 代码BLX 指令执行时:

拷贝下一条指令的地址到 LR 寄存器。引起处理器转移到 label或 Rm 存储的地址。如果 Rm 的位 [0]清 0,或使用格式 1, 则指令集切换到 ARM 状态。

Page 194: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (五)堆栈指令• 功能:低寄存器和可选的 LR 进栈。低寄存器和可选的 PC 出栈。• 格式: POP { <Reglist> { , PC}}• PUSH { <Reglist> { , LR}}• • 其中: Reglist 低寄存器范围的、用逗号隔开的列表。• 注释:

– 1. Thumb 堆栈是满递减堆栈,向下增长,且 SP 指向堆栈的最后入口。

– 2.寄存器以数字顺序存储在堆栈中。最低数字的寄存器其地址最低。

– 3. POP{reglist,PC} 这条指令引起处理器转移到从堆栈弹出给 PC 的地址。这通常是从子程序返回,其中 LR 在子程序开头压进堆栈。

– 4.指令采用基址回写,因此基址寄存器不应出现在 寄存器列表中。

Page 195: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 条件码标志– 这些指令不影响条件码标志

• 例 : • PUSH {R0,R4-R7} ; R0 、 R4~R7 进栈• PUSH {R0,LR} • POP {R2,R5} • POP {R0-R7,PC} ;出栈并从子程序返回

Page 196: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (六)寄存器读取和存储指令• 单寄存器读取和存储

– Thumb 单寄存器传送类指令是 ARM 单寄存器传送类指令的一个子集,和 ARM 有相同的指令格式。

• 多寄存器读取和存储指令– Thumb 多寄存器传送类指令和 ARM 有相同的指

令格式。

Page 197: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (七)移位和循环移位操作• ASR 、 LSL 、 LSR 和 ROR运算 • 功能:移位和循环移位操作。这些指令可使用

寄存器中的值或立即数来表示偏移量。• 格式 1 : < 操作码 > Rd , Rn , < #immed>

15 0

0 0 0

6

#5位立即数

51013 11

Op

3 2

Rn Rd

< 操作码 > : ASR 、 LSL 、 LSRRd : 立即数移位的目的寄存器。 Rd必须在 R0~R7 范围内。Rn : 立即数移位的源寄存器。 Rn必须在 R0~R7 范围内。< #immed>:立即数移位量。它是一个取值为整数的表达式。整数的范围如下: — < 操作码 > 若是 LSL ,则为 0~31 ; — 其它则为 1~32 。

Page 198: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 格式 2 : < 操作码 > Rd , Rs • 编码结构:

15 0

0 1 0 0 0 0 Rd

3

Rs5 269

Op

10

其中:< 操作码 > : ASR 、 LSL 、 LSR 、 ROR 。Rd : 目的寄存器,它也是第 1 操作数寄存器。 Rd必须在 R0~R7 范围内。Rs : 在寄存器控制移位中包含移位量的寄存器。 Rs必须 在 R0~R7 范围内,只有 Rs 的最低有效字节可用作偏 移量。

Page 199: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 条件标志位:– 对于除 ROR 以外的所有指令,若移位量为 32 ,

则 Rd清 0 ,最后移出的位保留在标志 C 中,并根据结果影响 N 、 Z 标志位。若移位量大于 32 ,则 Rd 和标志 C 均被清 0 ,并根据结果影响 N 、Z 标志位。

– 对于 ROR 指令,若移位量为 32 ,则 Rd 不变且不影响标志位;若移位量大于或小于 32 时,则最后移出的位将存入到 C 中,并根据结果影响 N 、Z 标志位。

– 任何情况都不影响标志 V 。

Page 200: 嵌入式系统讲义 第 3 章   ARM 指令系统

• 例:• ASR R3,R5

• LSR R0,R2,#6

• LSR R5,R5,zyb

• LSL R0,R4,#0

• ROR R2,R3

;将 R3 中的值算术右移 R5次后再放入 R3 。;将 R2 中的值逻辑右移 6次后放入 R0 。

; zyb必须取值为 1~32 的整数。

;将 R4 的内容放到 R0 中,除不影响标志位 C 和 V 外,同 MOV R0,R4

; R2 中的值循环右移 R3次后放入 R2中。

Page 201: 嵌入式系统讲义 第 3 章   ARM 指令系统

• (八)数据处理指令• 除移位操作之外的数据处理指令,和 ARM

类似。

Page 202: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 203: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 204: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 205: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 206: 嵌入式系统讲义 第 3 章   ARM 指令系统
Page 207: 嵌入式系统讲义 第 3 章   ARM 指令系统