Upload
zahi
View
134
Download
0
Embed Size (px)
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
Citation preview
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 指令集
2TM 234v11 ARM 及 Thumb 指令集
ARM 指令小节目录
1. 指令格式2. 条件码3. 存储器访问指令4. 数据处理指令5. 乘法指令6.ARM 分支指令7. 杂项指令8. 伪指令
3TM 334v11 ARM 及 Thumb 指令集
ARM 指令长度概述 ARM指令长度
指令集可以是以下任一种32 bits 长 (ARM状态 )16 bits 长 (Thumb 状态 )
ARM7TDMI 支持 3 种数据类型字节 (8-bit)半字 (16-bit)字 (32-bit)
字必须被排成 4 个字节边界对齐 , 半字必须被排列成 2 个字节边界对齐
4TM 434v11 ARM 及 Thumb 指令集
ARM 指令长度概述向后兼容:新版本增加指令,并保持指令向后兼容;
Load-store 结构 *load/store –从存储器中读某个值 , 操作完后再将其放回存储器中
只对存放在寄存器的数据进行处理对于存储器中的数据,只能使用 load/store指令进行存取
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 ; 文件结束
使用“;”进行注释
标号顶格写实际代码段
声明文件结束
6TM 634v11 ARM 及 Thumb 指令集
4.2 指令集介绍
ARM 指令集——指令格式
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例:
8TM 834v11 ARM 及 Thumb 指令集
ARM 指令的基本格式如下:
4.2 指令集介绍
ARM 指令集——第 2 个操作数
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
灵活的使用第 2 个操作数“ operand2”能够提高代码效率。它有如下的形式:
#immed_8r—— 常数表达式;Rm—— 寄存器方式;Rm,shift—— 寄存器移位方式;
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 位常数
10TM 1034v11 ARM 及 Thumb 指令集
4.2 指令集介绍
ARM 指令集——第 2 个操作数
Rm—— 寄存器方式
在寄存器方式下,操作数即为寄存器的数值。
例如:SUB R1,R1,R2
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位有效。
12TM 1234v11 ARM 及 Thumb 指令集
桶形移位器
ALU
桶形移位器
Rd
结果 N
RmRn
4.2 指令集介绍
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 指令集介绍
14TM 1434v11 ARM 及 Thumb 指令集
4.2 指令集介绍
ARM 指令集——第 2 个操作数
LSL 移位操作: 0
LSR 移位操作: 0
ASR 移位操作:
ROR 移位操作:
RRX 移位操作: C
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
16TM 1634v11 ARM 及 Thumb 指令集
ARM 指令目录
1. 指令格式2. 条件码3. 存储器访问指令4. 数据处理指令5. 乘法指令6.ARM 分支指令7. 杂项指令8. 伪指令
17TM 1734v11 ARM 及 Thumb 指令集
ARM 指令的基本格式如下:
4.2 指令集介绍
ARM 指令集——条件码
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
使用条件码“ cond”可以实现高效的逻辑操作 ( 节省跳转和条件语句 ) ,提高代码效率。
所有的 ARM 指令都可以条件执行,而 Thumb 指令只有 B (跳转)指令具有条件执行 功能。如果指令不标明条件代码,将默认为无条件( AL )执行。
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 任何 从不执行 ( 不要使用 )
指令条件码表
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
示例:
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 ,并设置标志位
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 为默认状态,不需要单独指出
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
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
24TM 2434v11 ARM 及 Thumb 指令集
4.2 指令集介绍
ARM 指令集——存储器访问指令
ARM 处理器是典型的 RISC 处理器,对存储器的访问只能使用加载和存储指令实现。 ARM7 处理器是冯•诺依曼存储结构, RAM 存储空间及 I/O 映射空间统一编址,除对 RAM 操作以外,对外围 IO 、程序数据的访问均要通过加载 / 存储指令进行。
存储器访问指令分为单寄存器操作指令和多寄存器操作指令。
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 存储器访问指令——单寄存器加载
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 寄存器,则实现程序跳转功能,这样也就实现了程序散转。
所有单寄存器加载 / 存储指令可分为“字和无符号字节加载存储指令”和“半字和有符号字节加载存储指令。
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。
28TM 2834v11 ARM 及 Thumb 指令集
ARM 存储器访问指令——单寄存器存储
•LDR和 STR—— 字和无符号字节加载 / 存储指令编码
指令执行的条件码
I为 0 时,偏移量为12 位立即数,为 1时 ,偏移 量 为 寄 存器移位
P表示前 /后变址
U表示加 / 减
B 为 1 表 示 字 节 访问,为 0 表示字访问
W 表示回写
为指令的寻址方式Rd 为源 / 目标寄存器Rn 为基址寄存器
L用于区别加载( L为1 )或存储( L为 0 )
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]
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]
31TM 3134v11 ARM 及 Thumb 指令集
ARM 存储器访问指令——单寄存器存储
从寻址方式的地址计算方法分,加载 / 存储指令有以下4 种格式: 零偏移。 如: LDR Rd,[Rn]
前索引偏移。 如: LDR Rd,[Rn,#0x04]!
程序相对偏移。 如: LDR Rd,labe1
后索引偏移。 如: LDR Rd,[Rn],#-0x04
注意:必须保证字数据操作的地址是 32 位对齐的。
•LDR和 STR—— 字和无符号字节加载 / 存储指令
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.半字读写的指定地址必须为偶数,否则将产生不可靠的结果;
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 表示字节访问
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 存储器访问指令——单寄存器存储
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]
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]
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]
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
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]
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]!
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 个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。
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 )数据传入或传出的是用户模式下的寄存器,而不是当前模式的寄存器。
43TM 4334v11 ARM 及 Thumb 指令集
ARM 存储器访问指令——多寄存器存取
•LDM和 STM—— 多寄存器加载 / 存储指令编码
指令执行的条件码
S 对 应 于 指 令 中的” ^” 符号
P表示前 /后变址U表示加 / 减
W 表示回写
寄存器列表Rn 为基址寄存器L用于区别加载( L为1 )或存储( L为 0 )
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 实现堆栈操作。
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
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 种模式,它们之间的关系如下表所示:
47TM 4734v11 ARM 及 Thumb 指令集
堆栈是一个按特定顺序进行存取的存储区,操作顺序为“后进先出” 。堆栈寻址是隐含的,它使用一个专门的寄存器 ( 堆栈指针 ) 指向一块存储区域 ( 堆栈 ) ,指针所指向的存储单元即是堆栈的栈顶。存储器堆栈可分为两种:
向上生长:向高地址方向生长,称为递增堆栈向下生长:向低地址方向生长,称为递减堆栈
4.1 ARM 处理器寻址方式
寻址方式分类——堆栈寻址
48TM 4834v11 ARM 及 Thumb 指令集
4.1 ARM 处理器寻址方式
寻址方式分类——堆栈寻址
栈底
栈顶
栈区
SP
堆栈存储区
栈顶
栈底
栈区
SP
向下增长
向上增长
0x12345678
0x12345678堆栈压栈
堆栈压栈
49TM 4934v11 ARM 及 Thumb 指令集
栈顶SP栈顶SP
栈底
空堆栈
栈底
满堆栈
堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个待压入数据的空位置,称为空堆栈。
4.1 ARM 处理器寻址方式
寻址方式分类——堆栈寻址
0x12345678
0x12345678栈顶SP 0x12345678
栈顶SP
压栈 压栈
50TM 5034v11 ARM 及 Thumb 指令集
所以可以组合出四种类型的堆栈方式:满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如 LDMFA、 STMFA 等; 空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如 LDMEA、 STMEA 等; 满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如 LDMFD、 STMFD 等;空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如 LDMED、 STMED 等。
4.1 ARM 处理器寻址方式 寻址方式分类——堆栈寻址
LDMIA R4,{R0,R1,R2,R3,R5}
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}
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 相同。
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 的内容写入到该内存单元中
;(最低字节有效 )
54TM 5434v11 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
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 方式寻址
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
58TM 5834v11 ARM 及 Thumb 指令集
LDM / STM 指令允许一次传送 1 到 16 个寄存器到 / 从存储器中。 寄存器传送顺序不能被指定• 最小数字的寄存器总是被传送到 /从存储器的最低地址上。
LDMIA r10,{r0,r1,r4}
基址寄存器指定存储器访问开始的地址
块传送指令针对下列情况很有效:• 从存储器中搬运一块数据• 保存或恢复堆栈中的内容
• 如果是慢速存储器,会影响中断响应时间
块数据传送
r1
r4
r0r10 地址增加
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)
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}
61TM 6134v11 ARM 及 Thumb 指令集
在寄存器和存储器之间,由一次存储器读和一次存储器写组成的原子操作。完成一个字节或字的交换。
语法: SWP{<cond>}{B} Rd, Rm, [Rn]
Rm Rd
32
1temp
存储器
Rn
SWP
62TM 6234v11 ARM 及 Thumb 指令集
4.2 指令集介绍
ARM 指令集——分支指令
在 ARM 中有两种方式可以实现程序的跳转,一种是使用分支指令直接跳转,另一种则是直接向PC 寄存器赋值实现跳转。 分支指令有以下三种:
分支指令 B ;带链接的分支指令 BL ;带状态切换的分支指令 BX 。
63TM 6334v11 ARM 及 Thumb 指令集
ARM 分支指令——指令编码
•分支指令 B/BL 指令编码格式
指令执行的条件码 L区别 B 指令( L为0 ) 和 BL 指 令 ( L为 1 )
24 位 有 符 号立即 数(偏移量)
•分支指令 BX 指令编码格式
指令执行的条件码 Rm 目标地址寄存器,该寄存器装载跳转地址
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 指令——分支指令
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 处
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
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
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 的最低位来切换处理器状态
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
70TM 7034v11 ARM 及 Thumb 指令集
寄存器 , 可选择是否增加移位操作 . 移位值可以是:
5 bit 无符号整数 放在另一个寄存器的低字节
用于常数乘法
立即数 8 bit ,大小范围 0-255。
右移偶数位 允许直接加载 32-bit 常数到寄存器中。
结果
操作数 1
BarrelShifter
操作数 2
ALU
桶型移位器 :第二个操作数
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)
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)
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常数
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 指令 ?
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 并执行
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 周期
以上均为一般规则,确切细节查看相应手册。
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
条件域
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
79TM 7934v11 ARM 及 Thumb 指令集
协处理器指令
ARM体系支持 16 个协处理器 针对每个协处理器的指令占用 ARM 指令集中的固定部分
如果相应的协处理器不存在, 将发生一个未定义指令异常。 这有三种协处理器指令
协处理器数据处理指令 CDP :初始化协处理器数据处理操作
协处理器寄存器传送指令 MRC :从协处理器寄存器移到 ARM 寄存器 MCR :从 ARM 寄存器移到协处理器寄存器
协处理器存储器传送指令 LDC :从存储器装载到协处理器寄存器 STC :从协处理器寄存器存储到存储器
80TM 8034v11 ARM 及 Thumb 指令集
测试 #4
1. 写几条 ARM 指令,使能 IRQ 中断
2. 下列 ARM 指令将做什么 ?a) LDRH r0,[r1,#6]b) LDR r0, =0x999
3. 在装载或存储指令中, “ !” 表示什么 ?
4. 当 执行 SWI 指令时,会发生什么 ?
5. SWP 指令的优势是什么 ?
81TM 8134v11 ARM 及 Thumb 指令集
议程
ARM 指令集 Thumb 指令集
v5TE体系结构扩展
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 指令
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
84TM 8434v11 ARM 及 Thumb 指令集
写 Thumb汇编程序
Thumb 不是一个“好” 指令集! 最好用编译器来产生 约束并不一致
代码处理通常优于 ARM 指令
更多细节,参看: ARM “Architecture Reference Manual” Chapters A6和 A7
85TM 8534v11 ARM 及 Thumb 指令集
议程
ARM 指令集
Thumb 指令集 v5TE体系结构扩展
86TM 8634v11 ARM 及 Thumb 指令集
v5TE 结构
v5TE体系包括全部的 v4T ARM和 Thumb 指令集,还有:
更支持 interworking 同时支持 ARM / Thumb 状态
Breakpoint 指令 (ARM和 Thumb) CLZ( Count Leading Zeros )指令 扩展协处理器指令 - MCR2 等等 支持饱和处理 封装的带符号的半字乘法指令 双字装载 / 存储指令 Cache预装载指令 双字协处理器 传送指令 - MCRR/MRRC
87TM 8734v11 ARM 及 Thumb 指令集
你采用的处理器是哪种结构 ?
处理器核 结构体系
7TDMI & 9TDMI v4T
9E-S rev1 v5TE
926EJ-S/1026EJ-S v5TEJ
1020E v5TE
StrongARM v4
XScale Microarchitecturev5TE
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
89TM 8934v11 ARM 及 Thumb 指令集
扩展协处理器指令
CDP2, LDC2, STC2, MCR2, MRC2 新格式的标准协处理器指令为协处理器设计人员提供了附加的操作码空间。 同样是无条件执行的
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’ 位 )
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]
92TM 9234v11 ARM 及 Thumb 指令集
饱和算术
0x7FFFFFFF 加上 1 产生一个负的结果
0x80000000 减去 1 ,会产生一个正的结果
饱和算术指令会区分这两种情况,使得在最大值和最小值越界时产生饱和
经常用于表示 1 到 -1 “Q31” 算术 AXD 可以显示 Q31 格式
0x0
0x7FFFFFFF
0x80000000
-ve
+ve
- Most Positive Number
- Most Negative Number
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
94TM 9434v11 ARM 及 Thumb 指令集
R1 = 0x7F000000
+ Saturate
R2 = 0x00001000
0x7F001000
0x7F001000
+ Saturate
R1 = 0x7F000000
R3 = 0x01000000
0x80000000
0x7FFFFFFF
QADD 示例
例 1 没有超过最大值边界,因此不会产生饱和 例 2 计算结果超过最大值边界,因此产生饱和且标志位 Q 被置位
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
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
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) 。
98TM 9834v11 ARM 及 Thumb 指令集
Cache 预读
PLD [Rn,<offset>]
偏移量可以是 无符号 12 位立即数 (ie 0 - 4095 bytes). 寄存器,可以使用立即数移位操作
偏移量可以为正的,也可以为负
通知存储器系统某一地址的数据极可能即将被访问 存储器系统将数据调入缓存以便后面访问 对于不支持该操作的存储器系统,该指令 相当于 NOP。
无条件执行
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 会产生不可预知的问题
100TM 10034v11 ARM 及 Thumb 指令集
测试 #6
1) CLZ 可用于那些运算?
2) 哪一条指令会置位标志位 Q?
3) 标志位 Q 值为后,怎样清零?
4) 下面这条指令合法吗?
LDRD r7, [r1,#0x100]
5) PLD 指令做什么操作?
6) 哪些 ARM 指令总是无条件执行?
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
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
分支指令