ARM 及 Thumb 指令集

103
1 TM T H E A R C H I T E C T U R E F O R T H E D I G I T A L W O R L D ARM 及 Thumb 及及及

description

ARM 及 Thumb 指令集. ARM 指令小节目录. 1. 指令格式 2. 条件码 3. 存储器访问指令 4. 数据处理指令 5. 乘法指令 6.ARM 分支指令 7. 杂项指令 8. 伪指令. ARM 指令长度概述. ARM 指令长度 指令集可以是以下任一种 32 bits 长 (ARM 状态 ) 16 bits 长 (Thumb 状态 ) ARM7TDMI 支持 3 种数据类型 字节 (8-bit) 半字 ( 16-bit) 字 (32-bit) 字必须被排成 4 个字节边界对齐 , 半字必须被排列成 2 个字节边界对齐. - PowerPoint PPT Presentation

Transcript of ARM 及 Thumb 指令集

Page 1: ARM 及 Thumb 指令集

1TMT H E A R C H I T E C T U R E F O R T H E D I G I T A L W O R L D

ARM及 Thumb 指令集

Page 2: ARM 及 Thumb 指令集

2TM 234v11 ARM 及 Thumb 指令集

ARM 指令小节目录

1. 指令格式2. 条件码3. 存储器访问指令4. 数据处理指令5. 乘法指令6.ARM 分支指令7. 杂项指令8. 伪指令

Page 3: ARM 及 Thumb 指令集

3TM 334v11 ARM 及 Thumb 指令集

ARM 指令长度概述 ARM指令长度

指令集可以是以下任一种32 bits 长 (ARM状态 )16 bits 长 (Thumb 状态 )

ARM7TDMI 支持 3 种数据类型字节 (8-bit)半字 (16-bit)字 (32-bit)

字必须被排成 4 个字节边界对齐 , 半字必须被排列成 2 个字节边界对齐

Page 4: ARM 及 Thumb 指令集

4TM 434v11 ARM 及 Thumb 指令集

ARM 指令长度概述向后兼容:新版本增加指令,并保持指令向后兼容;

Load-store 结构 *load/store –从存储器中读某个值 , 操作完后再将其放回存储器中

只对存放在寄存器的数据进行处理对于存储器中的数据,只能使用 load/store指令进行存取

Page 5: ARM 及 Thumb 指令集

5TM 534v11 ARM 及 Thumb 指令集

简单的 ARM 程序; 文件名: TEST1.S

; 功能:实现两个寄存器相加

; 说明:使用 ARMulate 软件仿真调试

AREA Example1,CODE,READONLY ; 声明代码段 Example1

ENTRY ; 标识程序入口

CODE32 ; 声明 32位 ARM 指令

START MOV R0,#0 ; 设置参数

MOV R1,#10

LOOP BL ADD_SUB ; 调用子程序 ADD_SUB

B LOOP ; 跳转到 LOOP

ADD_SUB

ADDS R0,R0,R1 ;R0 = R0 + R1

MOV PC,LR ; 子程序返回

END ; 文件结束

使用“;”进行注释

标号顶格写实际代码段

声明文件结束

Page 6: ARM 及 Thumb 指令集

6TM 634v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——指令格式

Page 7: ARM 及 Thumb 指令集

7TM 734v11 ARM 及 Thumb 指令集

ARM 是三地址指令格式,指令的基本格式如下:

4.2 指令集介绍

ARM 指令集——基本指令格式

<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

其中 <> 号内的项是必须的, {} 号内的项是可选的。各项的说明如下:

opcode :指令助记符; cond :执行条件;

S :是否影响 CPSR 寄存器的值;

Rd :目标寄存器; Rn :第 1 个操作数的寄存器;

operand2 :第 2 个操作数;指令语法 目标寄存器( Rd) 源寄存器 1(Rn) 源寄存器 2(Rm)

ADD r3,r1,r2 r3 r1 r2例:

Page 8: ARM 及 Thumb 指令集

8TM 834v11 ARM 及 Thumb 指令集

ARM 指令的基本格式如下:

4.2 指令集介绍

ARM 指令集——第 2 个操作数

<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

灵活的使用第 2 个操作数“ operand2”能够提高代码效率。它有如下的形式:

#immed_8r—— 常数表达式;Rm—— 寄存器方式;Rm,shift—— 寄存器移位方式;

Page 9: ARM 及 Thumb 指令集

9TM 934v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——第 2 个操作数

#immed_8r—— 常数表达式

该常数必须对应 8 位位图,即一个 8 位的常数通过循环右移偶数位得到。

循环右移 10 位

0x120 0 0 1 0 0 1 0

0x000 0 0 0 0 0 0 0

0x000 0 0 0 0 0 0 0

0x000 0 0 0 0 0 0 0

0x000 0 0 0 0 0 0 0

0x000 0 0 0 0 0 0 0

0x801 0 0 0 0 0 0 0

0x040 0 0 0 0 1 0 0

8 位常数

Page 10: ARM 及 Thumb 指令集

10TM 1034v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——第 2 个操作数

Rm—— 寄存器方式

在寄存器方式下,操作数即为寄存器的数值。

例如:SUB R1,R1,R2

Page 11: ARM 及 Thumb 指令集

11TM 1134v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——第 2 个操作数

Rm,shift—— 寄存器移位方式

将寄存器的移位结果作为操作数(移位操作不消耗额外的时间),但 Rm 值保持不变,移位方法如下:

操作码 说明 操作码 说明

ASR #n 算术右移 n 位 ROR #n 循环右移 n 位

LSL #n 逻辑左移 n 位 RRX 带扩展的循环右移 1 位

LSR #n 逻辑右移 n 位 Type RsType 为移位的一种类型, Rs 为偏移量寄存器,低 8位有效。

Page 12: ARM 及 Thumb 指令集

12TM 1234v11 ARM 及 Thumb 指令集

桶形移位器

ALU

桶形移位器

Rd

结果 N

RmRn

4.2 指令集介绍

Page 13: ARM 及 Thumb 指令集

13TM 1334v11 ARM 及 Thumb 指令集

桶形移位器操作

助记符 说明 移位操作 结果 Y 值

LSL 逻辑左移 x LSL y x<<y #0-31 or Rs

LSR 逻辑右移 x LSR y (unsigned)x>>y #1-32 or Rs

ASR 算术右移 x ASR y (signed)x>>Y #1-32 or Rs

ROR 算术左移 x ROR y ((unsigned)x>>y|(x<<32-y)) #1-32 or Rs

RRX 扩展的循环右移 x RRX y (c flag<<31)|((unsigned)x>>1) none

4.2 指令集介绍

Page 14: ARM 及 Thumb 指令集

14TM 1434v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——第 2 个操作数

LSL 移位操作: 0

LSR 移位操作: 0

ASR 移位操作:

ROR 移位操作:

RRX 移位操作: C

Page 15: ARM 及 Thumb 指令集

15TM 1534v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——第 2 个操作数

Rm,shift—— 寄存器移位方式

例如:ADD R1,R1,R1,LSL #3 ;R1=R1+R1<<3

SUB R1,R1,R2,LSR R3 ;R1=R1-R2>>R3

Page 16: ARM 及 Thumb 指令集

16TM 1634v11 ARM 及 Thumb 指令集

ARM 指令目录

1. 指令格式2. 条件码3. 存储器访问指令4. 数据处理指令5. 乘法指令6.ARM 分支指令7. 杂项指令8. 伪指令

Page 17: ARM 及 Thumb 指令集

17TM 1734v11 ARM 及 Thumb 指令集

ARM 指令的基本格式如下:

4.2 指令集介绍

ARM 指令集——条件码

<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}

使用条件码“ cond”可以实现高效的逻辑操作 ( 节省跳转和条件语句 ) ,提高代码效率。

所有的 ARM 指令都可以条件执行,而 Thumb 指令只有 B (跳转)指令具有条件执行 功能。如果指令不标明条件代码,将默认为无条件( AL )执行。

Page 18: ARM 及 Thumb 指令集

18TM 1834v11 ARM 及 Thumb 指令集

操作码 条件助记符 标志 含义

0000 EQ Z=1 相等

0001 NE Z=0 不相等

0010 CS/HS C=1 无符号数大于或等于

0011 CC/LO C=0 无符号数小于

0100 MI N=1 负数

0101 PL N=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 任何 从不执行 ( 不要使用 )

指令条件码表

Page 19: ARM 及 Thumb 指令集

19TM 1934v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——条件码

C 代码:

If(a > b)

a++;

Else

b++;

对应的汇编代码:

CMP R0,R1 ;R0( a )与 R1( b )比较

ADDHI R0,R0,#1 ; 若 R0>R1 , 则R0=R0+1

ADDLS R1,R1,#1 ; 若 R0≤1 , 则R1=R1+1

示例:

Page 20: ARM 及 Thumb 指令集

20TM 2034v11 ARM 及 Thumb 指令集

ARM 指令可以通过添加适当的条件码前缀来达到条件执行的目的。 这样可以提高代码密度,减少分支跳转指令数目,提高性能。 CMP r3,#0 CMP r3,#0

BEQ skip ADDNE r0,r1,r2 ADD r0,r1,r2skip

默认情况下,数据处理指令不影响条件码标志位,但可以选择通过添加“ S” 来影响标志位 。 CMP 不需要增加 “ S” 就可改变相应的标志位。

loop … SUBS r1,r1,#1 BNE loop

条件执行及标志位

如果 Z 标志清零则跳转

R1 减 1 ,并设置标志位

Page 21: ARM 及 Thumb 指令集

21TM 2134v11 ARM 及 Thumb 指令集

条件码

不等于( Not equal)无符号的大于或等于无符号的小于负数( Minus)

等于( Equal)

溢出( Overflow)没溢出无符号的大于无符号的小于或大于

正数或零

小于( Less Than)大于( Greater Than)小于等于总是执行( Always)

大于等于

EQNECS/HSCC/LO

PLVS

HILSGELTGTLEAL

MI

VC

Suffix 描述

Z=0C=1C=0

Z=1测试的标志位

N=1N=0V=1V=0C=1 & Z=0C=0 or Z=1N=VN!=VZ=0 & N=VZ=1 or N=!V

下表为所有可能的条件码: 注意 :AL 为默认状态,不需要单独指出

Page 22: ARM 及 Thumb 指令集

22TM 2234v11 ARM 及 Thumb 指令集

程序状态寄存器

条件位: N = Negative result from ALU Z = Zero result from ALU C = ALU operation Carried out V = ALU operation oVerflowed

Q 位: 仅 ARM 5TE/J 架构支持 指示饱和状态

J 位 仅 ARM 5TE/J 架构支持 J = 1: 处理器处于 Jazelle 状态

中断禁止位: I = 1: 禁止 IRQ. F = 1: 禁止 FIQ.

T Bit 仅 ARM xT 架构支持 T = 0: 处理器处于 ARM 状态 T = 1: 处理器处于 Thumb 状态

Mode 位: 处理器模式位

2731

N Z C V Q

28 67

I F T mode

1623

815

5 4 024

f s x c

U n d e f i n e dJ

Page 23: ARM 及 Thumb 指令集

23TM 2334v11 ARM 及 Thumb 指令集

条件执行示例

一系列的指令都使用条件指令if (a==0) func(1);

CMP r0,#0MOVEQ r0,#1BLEQ func

置标志位,再使用不同的条件码if (a==0) x=0;if (a>0) x=1;

CMP r0,#0MOVEQ r1,#0MOVGT r1,#1

使用条件比较指令if (a==4 || a==10) x=0;

CMP r0,#4CMPNE r0,#10MOVEQ r1,#0

Page 24: ARM 及 Thumb 指令集

24TM 2434v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——存储器访问指令

ARM 处理器是典型的 RISC 处理器,对存储器的访问只能使用加载和存储指令实现。 ARM7 处理器是冯•诺依曼存储结构, RAM 存储空间及 I/O 映射空间统一编址,除对 RAM 操作以外,对外围 IO 、程序数据的访问均要通过加载 / 存储指令进行。

存储器访问指令分为单寄存器操作指令和多寄存器操作指令。

Page 25: ARM 及 Thumb 指令集

25TM 2534v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

LDR Rd,addressing 加载字数据 Rd←[addressing], addressing索引 LDR{cond}

LDRB Rd,addressing 加载无符号字节数据 Rd←[addressing], addressing索引 LDR{cond}B

LDRT Rd,addressing 以用户模式加载字数据 Rd←[addressing], addressing索引 LDR{cond}T

LDRBT Rd, addressing 以用户模式加载无符号字节数据 Rd←[addressing], addressing索引 LDR{cond}BT

LDRH Rd, addressing 加载无符号半字数据 Rd←[addressing], addressing索引 LDR{cond}H

LDRSB Rd, addressing 加载有符号字节数据 Rd←[addressing], addressing索引 LDR{cond}SB

LDRSH Rd, addressing 加载有符号半字数据 Rd←[addressing], addressing 索引 LDR{cond}SH

ARM 存储器访问指令——单寄存器加载

Page 26: ARM 及 Thumb 指令集

26TM 2634v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

STR Rd, addressing 存储字数据 [addressing]←Rd ,

addressing 索引

STR{cond}

STRB Rd,addressing 存储字节数据 [addressing]←Rd ,

addressing 索引

STR{cond}B

STRT Rd,addressing 以用户模式存储字数据 [addressing]←Rd ,

addressing 索引

STR{cond}T

STRBT Rd,addressing 以用户模式存储字节数据 [addressing]←Rd ,

addressing 索引

STR{cond}BT

STRH Rd,addressing 存储半字数据 [addressing] ←Rd ,

addressing 索引

STR{cond}H

ARM 存储器访问指令——单寄存器存储

LDR/STR 指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等。若使用 LDR 指令加载数据到 PC 寄存器,则实现程序跳转功能,这样也就实现了程序散转。

所有单寄存器加载 / 存储指令可分为“字和无符号字节加载存储指令”和“半字和有符号字节加载存储指令。

Page 27: ARM 及 Thumb 指令集

27TM 2734v11 ARM 及 Thumb 指令集

•LDR和 STR—— 字和无符号字节加载 / 存储指令

LDR 指令用于从内存中读取单一字或字节数据存入寄存器中, STR 指令用于将寄存器中的单一字或字节数据保存到内存。指令格式如下:

ARM 存储器访问指令——单寄存器存储

LDR{cond}{T} Rd,< 地址 > ; 将指定地址上的字数据读入 Rd

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

LDR{cond}B{T} Rd,< 地址 > ; 将指定地址上的字节数据读入Rd

STR{cond}B{T} Rd,< 地址 > ;将 Rd 中的字节数据存入指定地址

其中, T为可选后缀。若指令有 T,那么即使处理器是在特权模式下,存储系统也将访问看成是在用户模式下进行的。 T在用户模式下无效,不能与前索引偏移一起使用 T。

Page 28: ARM 及 Thumb 指令集

28TM 2834v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——单寄存器存储

•LDR和 STR—— 字和无符号字节加载 / 存储指令编码

指令执行的条件码

I为 0 时,偏移量为12 位立即数,为 1时 ,偏移 量 为 寄 存器移位

P表示前 /后变址

U表示加 / 减

B 为 1 表 示 字 节 访问,为 0 表示字访问

W 表示回写

为指令的寻址方式Rd 为源 / 目标寄存器Rn 为基址寄存器

L用于区别加载( L为1 )或存储( L为 0 )

Page 29: ARM 及 Thumb 指令集

29TM 2934v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——单寄存器存储•LDR和 STR—— 字和无符号字节加载 / 存储指令 LDR/STR 指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。地址偏移量有以下 3 种格式: 立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

如: LDR R1,[R0,#0x12] ; R1<-[R0+0x12]

寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如: LDR R1,[R0,R2] ; R1<-[R0+R2]

LDR R1,[R0,-R2] ; R1<-[R0-R2]

寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

如: LDR R1,[R0,R2,LSL #2] ;R1<-[R0+R2*4]

Page 30: ARM 及 Thumb 指令集

30TM 3034v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——单寄存器存储•LDR和 STR—— 字和无符号字节加载 / 存储指令 LDR/STR 指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。地址偏移量有以下 3 种格式: 立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

如: LDR R1,[R0,#0x12] ; R1<-[R0+0x12]

寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如: LDR R1,[R0,R2] ; R1<-[R0+R2]

LDR R1,[R0,-R2] ; R1<-[R0-R2]

寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。

如: LDR R1,[R0,R2,LSL #2] ;R1<-[R0+R2*4]

Page 31: ARM 及 Thumb 指令集

31TM 3134v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——单寄存器存储

从寻址方式的地址计算方法分,加载 / 存储指令有以下4 种格式: 零偏移。 如: LDR Rd,[Rn]

前索引偏移。 如: LDR Rd,[Rn,#0x04]!

程序相对偏移。 如: LDR Rd,labe1

后索引偏移。 如: LDR Rd,[Rn],#-0x04

注意:必须保证字数据操作的地址是 32 位对齐的。

•LDR和 STR—— 字和无符号字节加载 / 存储指令

Page 32: ARM 及 Thumb 指令集

32TM 3234v11 ARM 及 Thumb 指令集

•LDR和 STR——半字和有符号字节加载 / 存储指令 这类 LDR/STR 指令可加载有符号半字或字节,可加载 /存储无符号半字。偏移量格式、寻址方式与加载 / 存储字和无符号字节指令相同。

ARM 存储器访问指令——单寄存器存储

LDR{cond}SB Rd,< 地址 > ; 将指定地址上的有符号字节读入 Rd

LDR{cond}SH Rd,< 地址 > ; 将指定地址上的有符号半字读入 Rd

LDR{cond}H Rd,< 地址 > ; 将指定地址上的半字数据读入 Rd

STR{cond}H Rd,< 地址 > ;将 Rd 中的半字数据存入指定地址注意:

1. 有符号位半字 / 字节加载是指用符号位加载扩展到 32 位,无符号半字加载是指用零扩展到 32 位;

2.半字读写的指定地址必须为偶数,否则将产生不可靠的结果;

Page 33: ARM 及 Thumb 指令集

33TM 3334v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——单寄存器存储

•LDR和 STR——半字和有符号字节加载 / 存储指令编码

指令执行的条件码

I为 0 时,偏移量为12 位立即数,为 1时 ,偏移 量 为 寄 存器移位

P表示前 /后变址

U表示加 / 减

W 表示回写

为指令的寻址方式Rd 为源 / 目标寄存器Rn 为基址寄存器L用于区别加载( L为1 )或存储( L为 0 )

S 为 1 表示有符号访问,为 0 表示无符号访问H为 1 表示半字访问,为 0 表示字节访问

Page 34: ARM 及 Thumb 指令集

34TM 3434v11 ARM 及 Thumb 指令集

•LDR和 STR 指令应用示例:1. 加载 / 存储字和无符号字节指令LDR R2,[R5] ;将 R5 指向地址的字数据存入 R2

STR R1,[R0,#0x04] ;将 R1 的数据存储到 R0+0x04 地址

LDRB R3,[R2],#-1 ;将 R2 指向地址的字节数据存入 R3, R2= R2- 1

STRB R0,[R3,-R8 ASR # 2] ;R0->[R3-R8/4], 存储 R0 的最低有效字节

2. 加载 / 存储半字和有符号字节指令LDRSB R1,[R0,R3] ;将 R0+R3 地址上的字节数据存入 R1 ,

;高 24 位用符号扩展

LDRH R6,[R2],#2 ;将 R2 指向地址的半字数据存入 R6 ,高 16 位用 0扩展

;读出后, R2=R2+2

STRH R1,[R0,#2]! ;将 R1 的半字数据保存到 R0+2 地址,

; 只修改低 2 字节数据,然后 R0=R0+2

ARM 存储器访问指令——单寄存器存储

Page 35: ARM 及 Thumb 指令集

35TM 3534v11 ARM 及 Thumb 指令集

练习 STR R1, [R2,R5]!

LDR R5, [R3, #-0X03]

STREQ R4 [R0, R4, LSL R5]

STREQ R4 [R6], #-0X08

LDR R0, [R2] !, -R6

LDRNE R4, R5, [R3, R6]

LDR R4 , START

LDR R1 , [R0] ! LDR [SP, #-0X04]

STR R1, START ;(必须保证 START 处可以存贮数据) LDR PC, R5

LDR PC , [R5]

Page 36: ARM 及 Thumb 指令集

36TM 3634v11 ARM 及 Thumb 指令集

半字和字节命令 STRB R5,[SP,R3]

LDRB R0,[R2],-R5, LSL,#0X02

LDRB PC, [R5]

STRB R0,[R15,#-0X02]!

LDRHNE R3,[R5,R8]

LDRH R6,[R15,#-0X20]!

STRH R0, [R4,R2,LSL# 0X02]

STRH R0,[PC,#0X08]

Page 37: ARM 及 Thumb 指令集

37TM 3734v11 ARM 及 Thumb 指令集

有符号半字和有符号字节命令

LDRSH R5 , [R3-R6]

LDRSB R0 , [R4], #0X0FF

LSRSH R15 , [R0-R6]

LSRSB R5, [R4,0X101]

LDRNESH R6, [SP,#0X06]!

STRSH R6, [R6]

Page 38: ARM 及 Thumb 指令集

38TM 3834v11 ARM 及 Thumb 指令集

T 后缀指令

LDRT R5,[R6,R7]

LDRBT R3,[R7],R0

STRBT R0,R2,LSL#0X01

STRT R7,[R3,#0X02]!

LDRT R5,[R7],R3,LSL#0X040

SDRT R5,R6,LSL#0X03

LDRT R6,START

Page 39: ARM 及 Thumb 指令集

39TM 3934v11 ARM 及 Thumb 指令集

目标寄存器器和基址寄存器是同一寄存器

LDR R4,[R4,R3,LSL#2]

LDR R4,[R4,R3,LSL#2]!

LDR R4,[R4],R3,LSL#2

LDR R4,[R3,R4,LSL#2]!

STR R4,[R4,R3,LSL#2]!

STR R4,[R4,R3,LSL#2]

Page 40: ARM 及 Thumb 指令集

40TM 4034v11 ARM 及 Thumb 指令集

使用 R15 时的数据传送

LDR R15,[R5]

LDR R6,[R15]

LDR R7,[R15,R7]!

STR R15,[R7,R1]

STR R0,[R15]

STR R0,[R15,R8]

STR R0,[R15,#0X4]!

Page 41: ARM 及 Thumb 指令集

41TM 4134v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

LDM{mode} Rn{!},reglist 多寄存器加载 reglist←[Rn...], Rn 回写等 LDM{cond}

{mode}

STM{mode} Rn{!},reglist 多寄存器存储 [Rn...]←reglist,Rn 回写等 STM{cond}

{mode}

ARM 存储器访问指令——多寄存器存取

多寄存器加载 / 存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。 LDM 为加载多个寄存器; STM 为存储多个寄存器。允许一条指令传送 16 个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。

Page 42: ARM 及 Thumb 指令集

42TM 4234v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——多寄存器存取 多寄存器加载 / 存储指令格式如下:

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

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

cond :指令执行的条件;模式:控制地址的增长方式,一共有 8 种模式;! :表示在操作结束后,将最后的地址写回 Rn 中;reglist :表示寄存器列表,可以包含多个寄存器,它们使用“ ,”隔开,如 {R1,R2,R6-R9} ,寄存器由小到大排列;^ :可选后缀。允许在用户模式或系统模式下使用。它有以下两个功能:

1 )若 op是 LDM且寄存器列表包含 R15 时,那么除了正常的多寄存器传送外,还将 SPSR 也复制到 CPSR 中。这用于异常处理返回,仅在异常模式下使用。

2 )数据传入或传出的是用户模式下的寄存器,而不是当前模式的寄存器。

Page 43: ARM 及 Thumb 指令集

43TM 4334v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——多寄存器存取

•LDM和 STM—— 多寄存器加载 / 存储指令编码

指令执行的条件码

S 对 应 于 指 令 中的” ^” 符号

P表示前 /后变址U表示加 / 减

W 表示回写

寄存器列表Rn 为基址寄存器L用于区别加载( L为1 )或存储( L为 0 )

Page 44: ARM 及 Thumb 指令集

44TM 4434v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——多寄存器存取 多寄存器加载 / 存储指令的 8 种模式如下表所示,右边四种为堆栈操作、左边四种为数据传送操作。

模式 说明 模式 说明

IA 每次传送后地址加 4 FD 满递减堆栈

IB 每次传送前地址加 4 ED 空递减堆栈

DA 每次传送后地址减 4 FA 满递增堆栈

DB 每次传送前地址减 4 EA 空递增堆栈

数据块传送操作 堆栈操作

进行数据复制时,先设置好源数据指针和目标指针,然后使用块拷贝寻址指令 LDMIA/STMIA、 LDMIB/STMIB、 LDMDA/STMDA、LDMDB/STMDB 进行读取和存储 。

进行堆栈操作操作时,要先设置堆栈指针( SP ),然后使用堆栈 寻 址 指 令 STMFD/LDMFD 、 STMED/LDMED 、 STMFA/LDMFA 和 STMEA/LDMEA 实现堆栈操作。

Page 45: ARM 及 Thumb 指令集

45TM 4534v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——多寄存器存取

数据块传送指令操作过程如右图所示,其中 R1 为指令执行前的基址寄存器, R1’则为指令执行后的基址寄存器。

R5

R6

R7

R1

R1’

指令 STMIA R1!,{R5-R7}

4008H

4004H

4000H

4014H

4010H

400CH

R5

R6

R7R1

R1’

指令 STMDA R1!,{R5-R7}

4008H

4004H

4000H

4014H

4010H

400CH

R5

R6

R7

R1

R1’

指令 STMIB R1!,{R5-R7}

4008H

4004H

4000H

4014H

4010H

400CH

R5

R6

R7

R1’

R1

指令 STMDB R1!,{R5-R7}

4008H

4004H

4000H

4014H

4010H

400CH

Page 46: ARM 及 Thumb 指令集

46TM 4634v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——多寄存器存取

数据块传送

存储

堆栈操作

压栈说明

数据块传送

加载

堆栈操作

出栈说明

STMDA STMED 空递减 LDMDA LDMFA 满递减

STMIA STMEA 空递增 LDMIA LDMFD 满递增

STMDB STMFD 满递减 LDMDB LDMEA 空递减

STMIB STMFA 满递增 LDMIB LDMED 空递增

; 使用数据块传送指令进行堆栈操作

STMDA R0!,{R5-R6}

. . .

LDMIB R0!,{R5-R6}

; 使用堆栈指令进行堆栈操作

STMED R13!,{R5-R6}

. . .

LDMED R13!,{R5-R6}

两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。

堆栈操作(详见“ 4.1 寻址方式堆栈寻址”)和数据块传送指令类似,也有 4 种模式,它们之间的关系如下表所示:

Page 47: ARM 及 Thumb 指令集

47TM 4734v11 ARM 及 Thumb 指令集

堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出” 。堆栈寻址是隐含的,它使用一个专门的寄存器 ( 堆栈指针 ) 指向一块存储区域 ( 堆栈 ) ,指针所指向的存储单元即是堆栈的栈顶。存储器堆栈可分为两种:

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

4.1 ARM 处理器寻址方式

寻址方式分类——堆栈寻址

Page 48: ARM 及 Thumb 指令集

48TM 4834v11 ARM 及 Thumb 指令集

4.1 ARM 处理器寻址方式

寻址方式分类——堆栈寻址

栈底

栈顶

栈区

SP

堆栈存储区

栈顶

栈底

栈区

SP

向下增长

向上增长

0x12345678

0x12345678堆栈压栈

堆栈压栈

Page 49: ARM 及 Thumb 指令集

49TM 4934v11 ARM 及 Thumb 指令集

栈顶SP栈顶SP

栈底

空堆栈

栈底

满堆栈

堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。

4.1 ARM 处理器寻址方式

寻址方式分类——堆栈寻址

0x12345678

0x12345678栈顶SP 0x12345678

栈顶SP

压栈 压栈

Page 50: ARM 及 Thumb 指令集

50TM 5034v11 ARM 及 Thumb 指令集

所以可以组合出四种类型的堆栈方式:满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如 LDMFA、 STMFA 等; 空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如 LDMEA、 STMEA 等; 满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如 LDMFD、 STMFD 等;空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如 LDMED、 STMED 等。

4.1 ARM 处理器寻址方式 寻址方式分类——堆栈寻址

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

Page 51: ARM 及 Thumb 指令集

51TM 5134v11 ARM 及 Thumb 指令集

数据块传送指令

STMFD R13! , {R0,R4-R6,R13}

LDMID R4,{R0,R1,R2,R3,R4,R6 }

LDMFD SP! , {R12,R15}

LDMFD SP! , {R12,R15}^

STMID R0, {R0-R5}

STMIA R1, {R0-R5}

Page 52: ARM 及 Thumb 指令集

52TM 5234v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

SWP Rd,Rm,Rn 寄存器和存储器字数据交换 Rd←[Rn] , [Rn]←Rm (Rn≠Rd 或Rm)

SWP{cond}

SWPB Rd,Rm,Rn 寄存器和存储器字节数据交换 Rd←[Rn] , [Rn]←Rm (Rn≠Rd 或Rm)

SWP{cond}B

ARM 存储器访问指令——寄存器和存储器交换指令

SWP 指令用于将一个内存单元 ( 该单元地址放在寄存器 Rn中 ) 的内容读取到一个寄存器 Rd 中,同时将另一个寄存器 Rm 的内容写入到该内存单元中。使用 SWP 可实现信号量操作。

指令格式如下:

SWP{cond}{B} Rd,Rm,[Rn]

其中, B 为可选后缀,若有 B ,则交换字节,否则交换 32 位字;Rd 用于保存从存储器中读入的数据; Rm 的数据用于存储到存储器中,若 Rm与 Rd 相同,则为寄存器与存储器内容进行互换; Rn 为要进行数据交换的存储器地址, Rn 不能与 Rd和 Rm 相同。

Page 53: ARM 及 Thumb 指令集

53TM 5334v11 ARM 及 Thumb 指令集

ARM 存储器访问指令——寄存器和存储器交换指令

•SWP和 SWPB—— 寄存器和存储器交换指令编码

指令执行的条件码B 用 于 区别无 符 号字节( B 为 1 )或字( B为 0 )

Rm源寄存器Rd 目标寄存器

Rn 为基址寄存器

•SWP 指令应用示例:SWP R1,R1,[R0] ; 将 R1 的内容与 R0 指向的存储单元的内容进行互换

SWPB R1,R2,[R0] ; 将 R0 指向的存储单元低字节数据读取到 R1 中

;( 高 24 位清零 ) ,并将 R2 的内容写入到该内存单元中

;(最低字节有效 )

Page 54: ARM 及 Thumb 指令集

54TM 5434v11 ARM 及 Thumb 指令集

复习

Page 55: ARM 及 Thumb 指令集

55TM 5534v11 ARM 及 Thumb 指令集

单寄存器数据传送

LDR STR Word LDRB STRB Byte LDRH STRH Halfword LDRSB 带符号的 byte load LDRSH 带符号的 halfword load

存储器系统必须支持所有访问宽度

语法: LDR{<cond>}{<size>} Rd, <address> STR{<cond>}{<size>} Rd, <address>

e.g. LDREQB

Page 56: ARM 及 Thumb 指令集

56TM 5634v11 ARM 及 Thumb 指令集

地址访问

LDR/STR 访问的地址由基址寄存器加上偏移量来产生。 针对 word 和无符号 byte 的访问 , 偏移量可以是:

一个无符号 12-bit立即数 ( 如 0 - 4095 bytes).LDR r0,[r1,#8]

一个寄存器,或再加上移位(由立即数指定)LDR r0,[r1,r2]LDR r0,[r1,r2,LSL#2]

可以是从基址寄存器上加或减去偏移量 :LDR r0,[r1,#-8]LDR r0,[r1,-r2]LDR r0,[r1,-r2,LSL#2]

对于 halfword 和带符号的 halfword / byte, 偏移量可以是 : 一个无符号 8 bit 立即数 ( 如 0-255 bytes). 一个寄存器 ( 不能偏移 ) 。

可选择采用 pre-indexed或 post-indexed 方式寻址

Page 57: ARM 及 Thumb 指令集

57TM 5734v11 ARM 及 Thumb 指令集

0x5

0x5

r1

0x200基址

寄存器 0x200

r0

0x5源寄存器for STR

偏移量12 0x20c

r1

0x200

原基址寄存器 0x200

r0

0x5源寄存器for STR

偏移量12 0x20c

r1

0x20c更新

基址寄存器

通过 STR r0,[r1,#12]! 来自动更新基址寄存器

Pre or Post Indexed 寻址 ?

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

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

Page 58: ARM 及 Thumb 指令集

58TM 5834v11 ARM 及 Thumb 指令集

LDM / STM 指令允许一次传送 1 到 16 个寄存器到 / 从存储器中。 寄存器传送顺序不能被指定• 最小数字的寄存器总是被传送到 /从存储器的最低地址上。

LDMIA r10,{r0,r1,r4}

基址寄存器指定存储器访问开始的地址

块传送指令针对下列情况很有效:• 从存储器中搬运一块数据• 保存或恢复堆栈中的内容

• 如果是慢速存储器,会影响中断响应时间

块数据传送

r1

r4

r0r10 地址增加

Page 59: ARM 及 Thumb 指令集

59TM 5934v11 ARM 及 Thumb 指令集

LDM / STM 操作

语法:<LDM|STM>{<cond>}<addressing_mode> Rb{!}, < 寄存器 list>

4 种寻址操作 : LDMIA / STMIA Increment After (先操作,后增加) LDMIB / STMIB Increment Before (先增加,后操作) LDMDA / STMDA Decrement After (先操作,后递减) LDMDB / STMDB Decrement Before (先递减,后操作)

IA

r1 地址

增加

r4

r0

r1

r4

r0

r1

r4

r0 r1

r4

r0

r10

IB DA DBLDMxx r10, {r0,r1,r4}STMxx r10, {r0,r1,r4}

基址寄存器 (Rb)

Page 60: ARM 及 Thumb 指令集

60TM 6034v11 ARM 及 Thumb 指令集

LDMFD sp!,{r4-r7,pc}

SP 100FF

1234AOBE80341010123484209753

r4 1r5 14544r6 0r7 12

lr 9048pc 9020

r4 100100FF r5 FF

1234 r6 1234A0BE r7 A0BE8034

pc 8034

堆栈

r4 100r5 FFr6 1234r7 A0BE

lr 8034

ABCD8765102E16FFFF1010123484209753

存储器顶

SP SP

100FF

1234A0BE8034

SP

Old SP

100FF

1234A0BE8034

ARM 堆栈操作通过块传送指令来完成 :• STMFD (Push) 块存储 - Full Descending stack [STMDB]• LDMFD (Pop) 块装载 - Full Descending stack [LDMIA]

STMFD sp!,{r4-r7,lr}

Page 61: ARM 及 Thumb 指令集

61TM 6134v11 ARM 及 Thumb 指令集

在寄存器和存储器之间,由一次存储器读和一次存储器写组成的原子操作。完成一个字节或字的交换。

语法: SWP{<cond>}{B} Rd, Rm, [Rn]

Rm Rd

32

1temp

存储器

Rn

SWP

Page 62: ARM 及 Thumb 指令集

62TM 6234v11 ARM 及 Thumb 指令集

4.2 指令集介绍

ARM 指令集——分支指令

在 ARM 中有两种方式可以实现程序的跳转,一种是使用分支指令直接跳转,另一种则是直接向PC 寄存器赋值实现跳转。 分支指令有以下三种:

分支指令 B ;带链接的分支指令 BL ;带状态切换的分支指令 BX 。

Page 63: ARM 及 Thumb 指令集

63TM 6334v11 ARM 及 Thumb 指令集

ARM 分支指令——指令编码

•分支指令 B/BL 指令编码格式

指令执行的条件码 L区别 B 指令( L为0 ) 和 BL 指 令 ( L为 1 )

24 位 有 符 号立即 数(偏移量)

•分支指令 BX 指令编码格式

指令执行的条件码 Rm 目标地址寄存器,该寄存器装载跳转地址

Page 64: ARM 及 Thumb 指令集

64TM 6434v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

B label 分支指令 PC←label B{cond}

BL label 带链接的分支指令 LR←PC-4, PC←label BL{cond}

BX Rm 带状态切换的分支指令 PC←Rm ,切换处理器状态 BX{cond}

ARM 指令——分支指令

Page 65: ARM 及 Thumb 指令集

65TM 6534v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

B label 分支指令 PC←label B{cond}

BL label 带链接的分支指令 LR←PC-4, PC←label BL{cond}

BX Rm 带状态切换的分支指令 PC←Rm ,切换处理器状态 BX{cond}

ARM 指令——分支指令

分支指令—— B 指令,该指令跳转范围限制在当前指令的 ±32M 字节地址内 (ARM 指令为字对齐,最低 2 位地址固定为 0) 。指令格式如下:

B{cond} Label

应用示例:

B WAITA ; 跳转到 WAITA 标号处

B 0x1234 ; 跳转到绝对地址 0x1234 处

Page 66: ARM 及 Thumb 指令集

66TM 6634v11 ARM 及 Thumb 指令集

BL Label

xxx

xxxLabelxxx

MOV PC,LR

Addr1

Addr2 xxx

xxx

LR

PC

助记符 说明 操作 条件码位置

B label 分支指令 PC←label B{cond}

BL label 带链接的分支指令 LR←PC-4, PC←label BL{cond}

BX Rm 带状态切换的分支指令 PC←Rm ,切换处理器状态 BX{cond}

ARM 指令——分支指令

带链接的分支指令—— BL 指令适用于子程序调用,使用该指令后,下一条指令的地址被拷贝到 R14(即 LR) 连接寄存器中,然后跳转到指定地址运行程序。跳转范围限制在当前指令的 ±32M 字节地址内。指令格式如下:

BL{cond} Label

Addr1Label

Addr2

Addr2

1.当程序执行到 BL 跳转指令时,硬件将下一条指令的地址 Addr2装入 LR 寄存器,并把跳转地址装入程序计数器( PC )

2. 程序跳转到目标地址Label继续执行,当子程序执行结束后,将 LR寄存器内容存入 PC ,返回调用函数继续执行

应用示例(调用子程序):

BL Label

Page 67: ARM 及 Thumb 指令集

67TM 6734v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

B label 分支指令 PC←label B{cond}

BL label 带链接的分支指令 LR←PC-4, PC←label BL{cond}

BX Rm 带状态切换的分支指令 PC←Rm ,切换处理器状态 BX{cond}

ARM 指令——分支指令

带状态切换的分支指令—— BX 指令,该指令可以根据跳转地址( Rm )的最低位来切换处理器状态。其跳转范围限制在当前指令的±32M 字节地址内 (ARM 指令为字对齐,最低 2 位地址固定为 0) 。指令格式如下:

BX{cond} Rm

跳转地址 Rm[0]

跳转后

CPSR 标志 T 位 处理器状态

0 0 ARM

1 1 Thumb

Page 68: ARM 及 Thumb 指令集

68TM 6834v11 ARM 及 Thumb 指令集

助记符 说明 操作 条件码位置

B label 分支指令 PC←label B{cond}

BL label 带链接的分支指令 LR←PC-4, PC←label BL{cond}

BX Rm 带状态切换的分支指令 PC←Rm ,切换处理器状态 BX{cond}

ARM 指令——分支指令

带状态切换的分支指令—— BX 指令,该指令可以根据跳转地址( Rm )的最低位来切换处理器状态。其跳转范围限制在当前指令的±32M 字节地址内 (ARM 指令为字对齐,最低 2 位地址固定为 0) 。 Rm的位 [0] 不用作地址的一部分。若 Rm 的位 [0]为 1 ,则指令将 CPSR 中的标志 T置位,且将目标地址的代码解释为 Thumb 代码;若 Rm 的位[0]为 0 ,则 Rm 的位 [1] 就不能为 1 。指令格式如下:

BX{cond} Rm 应用示例:

ADRL R0,ThumbFun+1 ;将 Thumb 程序的入口地址加 1 存入R0

BX R0 ; 跳转到 R0 指定的地址,

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

Page 69: ARM 及 Thumb 指令集

69TM 6934v11 ARM 及 Thumb 指令集

桶型移位器

DestinationCF 0 Destination CF

LSL : Logical Left Shift ASR: Arithmetic Right Shift

(无符号数)乘 2 除 2 ,并保留符号位

Destination CF...0 Destination CF

LSR : Logical Shift Right ROR: Rotate Right

(无符号数)除 2 位轮换

Destination

RRX: Rotate Right Extended

位轮换,从 CF到MSB 都参与操作

CF

Page 70: ARM 及 Thumb 指令集

70TM 7034v11 ARM 及 Thumb 指令集

寄存器 , 可选择是否增加移位操作 . 移位值可以是:

5 bit 无符号整数 放在另一个寄存器的低字节

用于常数乘法

立即数 8 bit ,大小范围 0-255。

右移偶数位 允许直接加载 32-bit 常数到寄存器中。

结果

操作数 1

BarrelShifter

操作数 2

ALU

桶型移位器 :第二个操作数

Page 71: ARM 及 Thumb 指令集

71TM 7134v11 ARM 及 Thumb 指令集

没有任何一条 ARM 指令可包括一个 32 bit 的立即数 所有的 ARM 指令都是 32 bits固定长度

数据处理指令格式中,第二个操作数有 12 位

4 bit 移位值 (0-15) 乘于 2 ,得到一个范围在 0-30 ,步长为 2 的移位值。 记住一条准则: “最后 8 位一定要移动偶数位” .

0711 8

immed_8

ShifterROR

rot

x2

Quick Quiz: 0xe3a004ffMOV r0, #???

立即数 (1)

Page 72: ARM 及 Thumb 指令集

72TM 7234v11 ARM 及 Thumb 指令集

Examples:

下列命令中,汇编器把立即数转换为移位操作: MOV r0,#4096 ; uses 0x40 ror 26 ADD r1,r2,#0xFF0000 ; uses 0xFF ror 16

也可使用 MVN 来进行位反转 : MOV r0, #0xFFFFFFFF ; assembles to MVN r0,#0

立即数不能使用上述方法产生 , 否则将导致错误。

031

ror #0

range 0-0xff000000 step 0x01000000 ror #8

range 0-0x000000ff step 0x00000001

range 0-0x000003fc step 0x00000004 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

立即数 (2)

Page 73: ARM 及 Thumb 指令集

73TM 7334v11 ARM 及 Thumb 指令集

为允许装载大常数,汇编器提供了一条伪指令 : LDR rd, =const

它可能汇编成下列指令: MOV or MVN。

或 LDR 指令,从数据池( Literal pools )读取常数。

For example LDR r0,=0xFF => MOV r0,#0xFF LDR r0,=0x55555555 => LDR r0,[PC,#Imm12]

……DCD 0x55555555

建议把常数装载到寄存器中时一律使用该伪指令。

装载 32 bit常数

Page 74: ARM 及 Thumb 指令集

74TM 7434v11 ARM 及 Thumb 指令集

测验 #1

1. 写一条 ARM 指令,分别完成下列操作:a) r0 = 16b) r0 = r1 / 16 ( 带符号的数字 )c) r1 = r2 * 3d) r0 = -r0

2. 下面哪些立即数是数据处理指令中有效的数据 ?

a) 0x00AB0000 b) 0x0000FFFF c) 0xF000000Fd) 0x08000012 e) 0x00001f80 f) 0xFFFFFFFF

3. BIC 指令做什么用?

4. 为什么 ARM 处理器增加了一条 RSB 指令 ?

Page 75: ARM 及 Thumb 指令集

75TM 7534v11 ARM 及 Thumb 指令集

Start

Stopr0 = r1?

r0 > r1?

r0 = r0 - r1 r1 = r1 - r0

Yes

No Yes

No

你只需要使用 CMP、 SUB和 B 指令。充分使用条件执行!

大家可以尝试计算 2109 和 4161 的 GCD

AREA myarea, CODEENTRY

MOV r0, #9MOV r1, #15

start; your code here

stopB stopEND

测验 #2 - GCD

新建一个 ‘ ARM Executable Image’ 项目

新建一个 text文件 另存为 “ gcd.s”

加入到项目中 Build 并执行

Page 76: ARM 及 Thumb 指令集

76TM 7634v11 ARM 及 Thumb 指令集

乘法

语法: MUL{<cond>}{S} Rd, Rm, Rs Rd = Rm * Rs MLA{<cond>}{S} Rd,Rm,Rs,Rn Rd = (Rm * Rs) + Rn [U|S]MULL{<cond>}{S} RdLo, RdHi, Rm, Rs RdHi,RdLo := Rm*Rs [U|S]MLAL{<cond>}{S} RdLo, RdHi, Rm, Rs RdHi,RdLo := (Rm*Rs)+RdHi,RdLo

占用的周期数 基本 MUL 指令

ARM7TDMI 上为 2-5 周期 StrongARM/XScale上为 1-3 周期 ARM9E/ARM102xE上为 2 周期

ARM9TDMI 比 ARM7TDMI多 1 周期 累加再多 1 周期 ( 不针对 9E ,尽管结果延迟多于 1周期 ) 对于“ long” 型数据,多 1 周期

以上均为一般规则,确切细节查看相应手册。

Page 77: ARM 及 Thumb 指令集

77TM 7734v11 ARM 及 Thumb 指令集

软件中断 (SWI)

产生一个异常陷阱,跳转到 SWI 硬件向量。 SWI 处理程序可以检测 SWI 号,从而决定采取何种操作。 通过 SWI机制,运行在用户模式下的应用程序,可请求操作系统执行一系列特权操作。

语法: SWI{<cond>} <SWI number>

2831 2427 0

Cond 1 1 1 1 SWI number (ignored by processor)

23

条件域

Page 78: ARM 及 Thumb 指令集

78TM 7834v11 ARM 及 Thumb 指令集

PSR 传送指令

MRS和MSR 允许传送 CPSR / SPSR 中的内容到 / 从一个通用寄存器中。 语法:

MRS{<cond>} Rd,<psr> ; Rd = <psr> MSR{<cond>} <psr[_fields]>,Rm ; <psr[_fields]> = Rm

在这里: <psr> = CPSR or SPSR [_fields] = ‘fsxc’ 的任意组合

也允许送一个立即数到 psr_fields MSR{<cond>} <psr_fields>,#Immediate

用户模式下,所有位均可以被读取,但只有条件标志位 (_f) 可被写。

2731

N Z C V Q

28 67

I F T mode

1623

815

5 4 024

f s x c

U n d e f i n e dJ

Page 79: ARM 及 Thumb 指令集

79TM 7934v11 ARM 及 Thumb 指令集

协处理器指令

ARM体系支持 16 个协处理器 针对每个协处理器的指令占用 ARM 指令集中的固定部分

如果相应的协处理器不存在, 将发生一个未定义指令异常。 这有三种协处理器指令

协处理器数据处理指令 CDP :初始化协处理器数据处理操作

协处理器寄存器传送指令 MRC :从协处理器寄存器移到 ARM 寄存器 MCR :从 ARM 寄存器移到协处理器寄存器

协处理器存储器传送指令 LDC :从存储器装载到协处理器寄存器 STC :从协处理器寄存器存储到存储器

Page 80: ARM 及 Thumb 指令集

80TM 8034v11 ARM 及 Thumb 指令集

测试 #4

1. 写几条 ARM 指令,使能 IRQ 中断

2. 下列 ARM 指令将做什么 ?a) LDRH r0,[r1,#6]b) LDR r0, =0x999

3. 在装载或存储指令中, “ !” 表示什么 ?

4. 当 执行 SWI 指令时,会发生什么 ?

5. SWP 指令的优势是什么 ?

Page 81: ARM 及 Thumb 指令集

81TM 8134v11 ARM 及 Thumb 指令集

议程

ARM 指令集 Thumb 指令集

v5TE体系结构扩展

Page 82: ARM 及 Thumb 指令集

82TM 8234v11 ARM 及 Thumb 指令集

015

31

0

ADDS r2,r2,#1

ADD r2,#1

32-bit ARM 指令

16-bit Thumb 指令

对于由编译器产生的大部分指令:没有条件执行源、目的寄存器必须相同仅能使用低寄存器常数大小有限制不能使用在线移位器

Thumb

Thumb 是 16-bit 指令集 代码密度优化 (总代码大小约为 ARM 指令的 65% ) 使用窄总线存储器时可以大大提高性能。 是 ARM 指令集的一个子集。

核存在一个执行状态 – Thumb 状态 ARM和 Thumb之间切换使用 BX 指令

Page 83: ARM 及 Thumb 指令集

83TM 8334v11 ARM 及 Thumb 指令集

使用 Branch Exchange 指令来完成 Interworking BX Rn ; Thumb 状态下的 Bx 指令 BX<condition> Rn ; ARM 状态下的 Bx 指令

也可以只是执行一个绝对跳转,无须状态更换。

ARM / Thumb 交互工作

Rn

BX 跳转的地址31 01

31 01

ARM / Thumb 选择0 - ARM 状态

1 - Thumb 状态

0

Page 84: ARM 及 Thumb 指令集

84TM 8434v11 ARM 及 Thumb 指令集

写 Thumb汇编程序

Thumb 不是一个“好” 指令集! 最好用编译器来产生 约束并不一致

代码处理通常优于 ARM 指令

更多细节,参看: ARM “Architecture Reference Manual” Chapters A6和 A7

Page 85: ARM 及 Thumb 指令集

85TM 8534v11 ARM 及 Thumb 指令集

议程

ARM 指令集

Thumb 指令集 v5TE体系结构扩展

Page 86: ARM 及 Thumb 指令集

86TM 8634v11 ARM 及 Thumb 指令集

v5TE 结构

v5TE体系包括全部的 v4T ARM和 Thumb 指令集,还有:

更支持 interworking 同时支持 ARM / Thumb 状态

Breakpoint 指令 (ARM和 Thumb) CLZ( Count Leading Zeros )指令 扩展协处理器指令 - MCR2 等等 支持饱和处理 封装的带符号的半字乘法指令 双字装载 / 存储指令 Cache预装载指令 双字协处理器 传送指令 - MCRR/MRRC

Page 87: ARM 及 Thumb 指令集

87TM 8734v11 ARM 及 Thumb 指令集

你采用的处理器是哪种结构 ?

处理器核 结构体系

7TDMI & 9TDMI v4T

9E-S rev1 v5TE

926EJ-S/1026EJ-S v5TEJ

1020E v5TE

StrongARM v4

XScale Microarchitecturev5TE

Page 88: ARM 及 Thumb 指令集

88TM 8834v11 ARM 及 Thumb 指令集

前导零计数指令

CLZ{cond} Rd, Rm 计算寄存器中的值有多少个前导 0

源寄存器从最高位开始计算。

1 个周期完成(ARM9E-S/ARM102x)

如果没有任何一位被置位,结果是 32 ;如果 bit 31被置位,结果为 0 。

Rm 左移 Rd 位即可标准化 Rm

带符号的标准化需要额外的 1 个周期

0000 0010 1110 1101...0R0 =

CLZ R1, R0

0x6R1 =

1011 1011 0100 0000...0Rm =

MOV R0, R0 LSL R1

EOR R1, R0, R0, LSL#1CLZ R1, R1MOV R0, R0, LSL R1

Page 89: ARM 及 Thumb 指令集

89TM 8934v11 ARM 及 Thumb 指令集

扩展协处理器指令

CDP2, LDC2, STC2, MCR2, MRC2 新格式的标准协处理器指令为协处理器设计人员提供了附加的操作码空间。 同样是无条件执行的

Page 90: ARM 及 Thumb 指令集

90TM 9034v11 ARM 及 Thumb 指令集

T

Rm Rs

B T B

W option

16 16 16 16

32 16

32/64

32/64

Rd(RdHi,RdLo)

Rn(RdHi,RdLo)

新的有符号乘法操作

SMULxy{cond} Rd, Rm, Rs

SMULWy{cond} Rd, Rm, Rs

SMLAxy{cond} Rd, Rm, Rs, Rn

SMLAWy{cond} Rd, Rm, Rs, Rn

SMLALxy{cond} RdLo, RdHi, Rm, Rs

SMLA 指令影响标志位 Q

x, y 用于选择寄存器的高一半和低一半 W 用于选择 48 位结果的高 32 位 不影响 NZCV ( 没有‘ S’ 位 )

Page 91: ARM 及 Thumb 指令集

91TM 9134v11 ARM 及 Thumb 指令集

1) 写一段汇编代码 ‘ qtest’ 测试标志位 Q 并清零。 源文件模板在文件 ‘ asm\dsp.s’ 中给出 返回根据标志位 Q 的值

2) 写一段汇编主程序,累加 16 位有符号数组的所有元素的平方。int total=0;for (n=0; n<64; n++)

total += x[n]*x[n];

取值指令 使用 LDRH 平方累加指令使用 SMLABB

3) 是否存在互锁 ?

4) 使用 AXD检查 Q 标志位 ( 通过改变 cpsr 模式为 E-PSR)

5) 在循环后面增加一个 BL 调用 qtest 并检查返回值

6) 专家题: 改用 LDR ,每次取两个值

7) 专家题: 修改代码,使用 64 位累加器

测试 #5 - DSP power calculation

xx[0]x[1]x[2]x[3]x[4]

x[63]

r0

x[62]x[5]

Page 92: ARM 及 Thumb 指令集

92TM 9234v11 ARM 及 Thumb 指令集

饱和算术

0x7FFFFFFF 加上 1 产生一个负的结果

0x80000000 减去 1 ,会产生一个正的结果

饱和算术指令会区分这两种情况,使得在最大值和最小值越界时产生饱和

经常用于表示 1 到 -1 “Q31” 算术 AXD 可以显示 Q31 格式

0x0

0x7FFFFFFF

0x80000000

-ve

+ve

- Most Positive Number

- Most Negative Number

Page 93: ARM 及 Thumb 指令集

93TM 9334v11 ARM 及 Thumb 指令集

饱和算术指令

饱和算术在几个通信 DSP 算法中是必须的 G.723.1 - VoIP AMR - Adaptive MultiRate

QSUB{cond} Rd, Rm, Rn Rd = saturate(Rm - Rn)

QADD{cond} Rd, Rm, Rn Rd = saturate(Rm + Rn)

QDSUB{cond} Rd, Rm, Rn Rd = saturate(Rm - saturate(Rn2))

QDADD{cond} Rd, Rm, Rn Rd = saturate(Rm + saturate(Rn2))

这些指令影响标志位 Q

Page 94: ARM 及 Thumb 指令集

94TM 9434v11 ARM 及 Thumb 指令集

R1 = 0x7F000000

+ Saturate

R2 = 0x00001000

0x7F001000

0x7F001000

+ Saturate

R1 = 0x7F000000

R3 = 0x01000000

0x80000000

0x7FFFFFFF

QADD 示例

例 1 没有超过最大值边界,因此不会产生饱和 例 2 计算结果超过最大值边界,因此产生饱和且标志位 Q 被置位

Page 95: ARM 及 Thumb 指令集

95TM 9534v11 ARM 及 Thumb 指令集

0x2000 (1/4) x 0x4000 (1/2) 0x08000000 (1/16) double & sat 0x10000000 (1/8)

S 1/2 1/4 1/8 1/16 1/32768

015

QDADD 示例 (1)

该示例表示 1/4 与 1/2 的 Q31 格式乘法,结果为 1/16 。产生该结果的原因是使用了 Q15 格式的整数乘法。

结果乘以 2 就得到了正确的结果( Q31 格式)。

QDADD 和 QDSUB 节省了现有的分离指令

Q15 format

Page 96: ARM 及 Thumb 指令集

96TM 9634v11 ARM 及 Thumb 指令集

QDADD 示例 (2)

输入 1 和 – 1 之间的乘数

乘法结果是 Q30 格式 **

QDADD 在加法操作之前将 Rn 转化为 Q31 格式

** 注: ARM 可以正确的处理 -1*-1 的情况

15S 15S

30SS

30S 0

+Rm

30S

SMULxy

QDADD

Q15 Q15

Q31

NowQ31

Q30

Page 97: ARM 及 Thumb 指令集

97TM 9734v11 ARM 及 Thumb 指令集

Load / Store 双寄存器

LDR/STR{<cond>}D <Rd>, <addressing_mode>

内存中两个相邻的字与寄存器对 (r0,r1), (r2,r3), (r4,r5), (r6,r7), (r8,r9), (r10,r11) 或 (r12,r13) 的传送

Rd 指示偶数寄存器号。相邻的奇数寄存器自动作为传送的第二个寄存器。

与 LDRH/STRH 寻址模式相同。

地址必须是双字对齐 (8-byte) 。

Page 98: ARM 及 Thumb 指令集

98TM 9834v11 ARM 及 Thumb 指令集

Cache 预读

PLD [Rn,<offset>]

偏移量可以是 无符号 12 位立即数 (ie 0 - 4095 bytes). 寄存器,可以使用立即数移位操作

偏移量可以为正的,也可以为负

通知存储器系统某一地址的数据极可能即将被访问 存储器系统将数据调入缓存以便后面访问 对于不支持该操作的存储器系统,该指令 相当于 NOP。

无条件执行

Page 99: ARM 及 Thumb 指令集

99TM 9934v11 ARM 及 Thumb 指令集

MRRC/ MCRR

MRRC{<cond>} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>

MCRR{<cond>} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>

传送两个 ARM 寄存器与协处理器而不是一个

提高了 ARM–coprocessor 传送带宽。提高代码宽度到 64 位

一条指令传送存放在两个 ARM 寄存器的双精度浮点数到一个浮点寄存器就是一个浮点协处理器的例子 。

使用 r15 会产生不可预知的问题

Page 100: ARM 及 Thumb 指令集

100TM 10034v11 ARM 及 Thumb 指令集

测试 #6

1) CLZ 可用于那些运算?

2) 哪一条指令会置位标志位 Q?

3) 标志位 Q 值为后,怎样清零?

4) 下面这条指令合法吗?

LDRD r7, [r1,#0x100]

5) PLD 指令做什么操作?

6) 哪些 ARM 指令总是无条件执行?

Page 101: ARM 及 Thumb 指令集

101TM 10134v11 ARM 及 Thumb 指令集

参考材料

ARM “Architecture Reference Manual” - 2nd editionedited by David Seal

ARM DDI 0100E is latest, covering v5TE DSP extensions ISBN 0-201-737191 (Addison-Wesley) PDF on ADS 和‘ Technical Documentation’ CDs

Steve Furber “ARM 系统 -on-chip architecture” - 2nd edition ISBN 0-201-67519-6 (Addison-Wesley)

Quick Reference Card ARM QRC 0001E comes with ADS 1.2

ADS 1.2 Assembler Guide refers to ADS Examples directory

Page 102: ARM 及 Thumb 指令集
Page 103: ARM 及 Thumb 指令集

103TM 10334v11 ARM 及 Thumb 指令集

Branch : B{<cond>} label

Branch with Link : BL{<cond>} subroutine_label

处理器核按偏移量左移两位,符号扩展,再把该值加到当前 PC 寄存器内 跳转范围: ± 32 Mbyte 如何执行长跳转?

2831 24 0

Cond 1 0 1 L 偏移量

条件码区域

Link bit 0 = Branch1 = Branch with link

232527

分支指令