ARM应用系统开发详解 --第3章 ARM微处理器的指令系统

 
本章介 ARM 指令集、 Thumb 指令集,以及各 指令 对应 址方式,通 过对 本章的 阅读 ,希望 者能了解 ARM 理器所支持的指令集及具体的使用方法。
本章的主要内容有:
ARM 指令集、 Thumb 指令集概述。
ARM 指令集的分 与具体 用。
Thumb 指令集 介及 合。
3.1 ARM 理器的指令集概述
3.1.1 A RM 理器的指令的分 与格式
ARM 理器的指令 集是加 / 型的, 即指令集 理寄存器中的数据 ,而且 果都要放回寄存器中,而 器的 访问则 需要通 过专门 的加 / 指令来完成。
ARM 理器的指令集可以分 指令、数据 理指令、程序状 寄存器( PSR 理指令、加 / 指令、 协处 理器指令和异常 生指令六大 ,具体的指令及功能如表 3-1 所示(表中指令 基本 ARM 指令,不包括派生的 ARM 指令)。
3-1 ARM 指令及功能描述
助记符
指令功能描述
ADC
带进位加法指令
ADD
加法指令
AND
逻辑与指令
B
跳转指令
BIC
位清零指令
BL
带返回的跳转指令
BLX
带返回和状态切换的跳转指令
BX
带状态切换的跳转指令
CDP
协处理器数据操作指令
CMN
比较反值指令
CMP
比较指令
EOR
异或指令
LDC
存储器到协处理器的数据传输指令
LDM
加载多个寄存器指令
LDR
存储器到寄存器的数据传输指令
MCR
ARM 寄存器到协处理器寄存器的数据传输指令
MLA
乘加运算指令
MOV
数据传送指令
MRC
从协处理器寄存器到 ARM 寄存器的数据传输指令
MRS
传送 CPSR SPSR 的内容到通用寄存器指令
MSR
传送通用寄存器到 CPSR SPSR 的指令
MUL
32 位乘法指令
MLA
32 位乘加指令
MVN
数据取反传送指令
ORR
逻辑或指令
RSB
逆向减法指令
RSC
带借位的逆向减法指令
SBC
带借位减法指令
STC
协处理器寄存器写入存储器指令
STM
批量内存字写入指令
STR
寄存器到存储器的数据传输指令
SUB
减法指令
SWI
软件中断指令
SWP
交换指令
TEQ
相等测试指令
TST
位测试指令

3.1.2 指令的条件域
理器工作在 ARM 态时 ,几乎所有的指令均根据 CPSR 中条件 的状 和指令的条件域有条件的 。当指令的 行条件 ,指令被 行,否 指令被忽略。
一条 ARM 指令包含 4 位的条件 ,位于指令的最高 4 [31:28] 。条件 共有 16 每种 条件 可用两个字符表示, 两个字符可以添加在指令助 符的后面和指令同 使用。例如,跳 指令 B 可以加上后 EQ 变为 BEQ 表示 相等 ,即当 CPSR 中的 Z 志置位 时发 生跳
16 条件 中,只有 15 可以使用,如表 3-2 所示,第 16 1111 保留, 暂时 不能使用。
3-2 指令的条件
条件码
助记符后缀
0000
EQ
Z 置位
相等
0001
NE
Z 清零
不相等
0010
CS
C 置位
无符号数大于或等于
0011
CC
C 清零
无符号数小于
0100
MI
N 置位
负数
0101
PL
N 清零
正数或零
0110
VS
V 置位
溢出
0111
VC
V 清零
未溢出
1000
HI
C 置位 Z 清零
无符号数大于
1001
LS
C 清零 Z 置位
无符号数小于或等于
1010
GE
N 等于 V
带符号数大于或等于
1011
LT
N 不等于 V
带符号数小于
1100
GT
Z 清零且( N 等于 V
带符号数大于
1101
LE
Z 置位或( N 不等于 V
带符号数小于或等于
1110
AL
忽略
无条件执行

3.2 ARM 指令的 址方式
谓寻 址方式就是 理器根据指令中 出的地址信息来 找物理地址的方式。目前 ARM 指令系 支持如下几 址方式。
3.2.1 立即
立即 址也叫立即数 址, 是一 特殊的 址方式,操作数本身就在指令中 出,只要取出指令也就取到了操作数。 个操作数被称 立即数, 对应 址方式也就叫做立即 址。例如以下指令:
ADD R0 R0 ,# 1 R0←R0 1
ADD R0 R0 ,# 0x3f R0←R0 0x3f
在以上两条指令中,第二个源操作数即 立即数,要求以 于以十六 制表示的立即数, 要求在 后加上 “0x” “&”
3.2.2 寄存器
寄存器 址就是利用寄存器中的数 操作数, 这种寻 址方式是各 理器 常采用的一 方式,也是一 种执 行效率 高的 址方式。以下指令:
ADD R0 R1 R2 R0←R1 R2
指令的 行效果是将寄存器 R1 R2 的内容相加,其 果存放在寄存器 R0 中。
3.2.2 寄存器
寄存器 址就是以寄存器中的 操作数的地址,而操作数本身存放在存 器中。例如以下指令:
ADD R0 R1 [R2] R0←R1 [R2]
LDR R0 [R1] R0←[R1]
STR R0 [R1] [R1]←R0
在第一条指令中,以寄存器 R2 操作数的地址,在存 器中取得一个操作数后与 R1 相加, 果存入寄存器 R0 中。
第二条指令将以 R1 值为 地址的存 器中的数据 送到 R0 中。
第三条指令将 R0 值传 送到以 R1 值为 地址的存 器中。
3.2.3 基址
基址 址就是将寄存器( 寄存器一般称作基址寄存器)的内容与指令中 出的地址偏移量相加,从而得到一个操作数的有效地址。 址方式常用于 访问 某基地址附近的地址 元。采用 址方式的指令常 有以下几 形式,如下所示:
LDR R0 [R1 ,# 4] R0←[R1 4]
LDR R0 [R1 ,# 4] R0←[R1 4] R1←R1 4
LDR R0 [R1] ,# 4 R0←[R1] R1←R1 4
LDR R0 [R1 R2] R0←[R1 R2]
在第一条指令中,将寄存器 R1 的内容加上 4 形成操作数的有效地址,从而取得操作数存入寄存器 R0 中。
在第二条指令中,将寄存器 R1 的内容加上 4 形成操作数的有效地址,从而取得操作数存入寄存器 R0 中,然后, R1 的内容自增 4 个字
在第三条指令中,以寄存器 R1 的内容作 操作数的有效地址,从而取得操作数存入寄存器 R0 中,然后, R1 的内容自增 4 个字
在第四条指令中,将寄存器 R1 的内容加上寄存器 R2 的内容形成操作数的有效地址,从而取得操作数存入寄存器 R0 中。
3.2.4 多寄存器
采用多寄存器 址方式,一条指令可以完成多个寄存器 送。 这种寻 址方式可以用一条指令 完成 送最多 16 个通用寄存器的 。以下指令:
LDMIA R0 {R1 R2 R3 R4} R1←[R0]
R2←[R0 4]
R3←[R0 8]
R4←[R0 12]
指令的后 IA 表示在 行完加 / 操作后, R0 按字 度增加,因此,指令可将 连续 储单 元的 值传 送到 R1 R4
3.2.5 对寻
与基址 址方式相 似,相 对寻 址以程序 数器 PC 的当前 值为 基地址,指令中的地址 号作 偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的 用和返回,跳 指令 BL 采用了相 对寻 址方 式:
BL NEXT ;跳 到子程序 NEXT 处执
……
NEXT
……
MOV PC LR ;从子程序返回
3.2.6 栈寻
是一 数据 构,按先 后出( First In Last Out FILO )的方式工作,使用一个称作堆 用寄存器指示当前的操作位置,堆 针总 是指向 栈顶
当堆 指向最后 入堆 的数据 ,称 为满 Full Stack ),而当堆 指向下一个将要放入数据的空位置 ,称 空堆 Empty Stack )。
,根据堆 的生成方式,又可以分 为递 增堆 Ascending Stack )和 减堆 Decending Stack ),当堆 由低地址向高地址生成 ,称 为递 增堆 ,当堆 由高地址向低地址生成 ,称 为递 减堆 这样 就有四 种类 型的堆 工作方式, ARM 理器支持 种类 型的堆 工作方式,即:
满递 增堆 :堆 指向最后 入的数据,且由低地址向高地址生成。
满递 减堆 :堆 指向最后 入的数据,且由高地址向低地址生成。
增堆 :堆 指向下一个将要放入数据的空位置,且由低地址向高地址生成。
减堆 :堆 指向下一个将要放入数据的空位置,且由高地址向低地址生成。
3.3 ARM 指令集
节对 ARM 指令集的六大 指令 详细 的描述。
3.3.1 指令
指令用于 实现 程序流程的跳 ,在 ARM 程序中有两 方法可以 实现 程序流程的跳
使用 专门 的跳 指令。
直接向程序 数器 PC 写入跳 地址
向程序 数器 PC 写入跳 地址 ,可以 实现 4GB 的地址空 中的任意跳 ,在跳 之前 合使用
MOV LR PC
似指令,可以保存将来的返回地址 ,从而 实现 4GB 连续 线 性地址空 的子程序 用。
ARM 指令集中的跳 指令可以完成从当前指令向前或向后的 32MB 的地址空 的跳 ,包括以下 4 条指令:
— B 指令
— BL 返回的跳 指令
— BLX 返回和状 的跳 指令
— BX 的跳 指令
1 B 指令
B 指令的格式
B{ 条件 } 地址
B 指令是最 简单 的跳 指令。一旦遇到一个 B 指令, ARM 理器将立即跳 定的目 地址,从那里 继续执 行。注意存 在跳 指令中的 实际值 是相 当前 PC 的一个偏移量,而不是一个 绝对 地址,它的 汇编 器来 算(参考 址方式中的 对寻 址)。它是 24 位有符号数,左移两位后有符号 32 位,表示的有效偏移 26 ( 前后 32MB 的地址空 ) 。以下指令:
B Label ;程序无条件跳 Label 处执
CMP R1 ,# 0 ;当 CPSR 寄存器中的 Z 条件 置位 ,程序跳 Label 处执
BEQ Label
2 BL 指令
BL 指令的格式
BL{ 条件 } 地址
BL 是另一个跳 指令,但跳 之前,会在寄存器 R14 中保存 PC 的当前内容,因此,可以通 R14 的内容重新加 PC 中,来返回到跳 指令之后的那个 指令 处执 行。 指令是 实现 子程序 用的一个基本但常用的手段。以下指令:
BL Label ;当程序无条件跳 Label 处执 ,同 将当前的 PC 保存到 R14
3 BLX 指令
BLX 指令的格式
BLX 地址
BLX 指令从 ARM 指令集跳 到指令中所指定的目 地址,并将 理器的工作状 ARM Thumb 指令同 PC 的当前内容保存到寄存器 R14 中。因此,当子程序使用 Thumb 指令集,而 用者使用 ARM 指令集 ,可以通 BLX 指令 实现 子程序的 用和 理器工作状 的切 。同 ,子程序的返回可以通 将寄存器 R14 值复 制到 PC 中来完成。
4 BX 指令
BX 指令的格式
BX{ 条件 } 地址
BX 指令跳 到指令中所指定的目 地址,目 地址 的指令既可以是 ARM 指令,也可以是 Thumb 指令。

3.3.2 数据 理指令
数据 理指令可分 数据 送指令、算 术逻辑 运算指令和比 指令等。
数据 送指令用于在寄存器和存 器之 间进 行数据的双向 传输
术逻辑 运算指令完成常用的算 逻辑 的运算, 该类 指令不但将运算 果保存在目的寄存器中,同 更新 CPSR 中的相 条件 志位。
指令不保存运算 果,只更新 CPSR 中相 的条件 志位。
数据 理指令包括:
— MOV 数据 送指令
— MVN 数据取反 送指令
— CMP 指令
— CMN 指令
— TST 测试 指令
— TEQ 相等 测试 指令
— ADD 加法指令
— ADC 带进 位加法指令
— SUB 减法指令
— SBC 借位减法指令
— RSB 逆向减法指令
— RSC 借位的逆向减法指令
— AND 逻辑 与指令
— ORR 逻辑 或指令
— EOR 逻辑 异或指令
— BIC 位清除指令
1 MOV 指令
MOV 指令的格式
MOV{ 条件 }{S} 目的寄存器,源操作数
MOV 指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加 到目的寄存器。其中 S 选项 决定指令的操作是否影响 CPSR 中条件 志位的 ,当没有 S 指令不更新 CPSR 中条件 志位的
指令示例:
MOV R1 R0 ;将寄存器 R0 值传 送到寄存器 R1
MOV PC R14 ;将寄存器 R14 值传 送到 PC ,常用于子程序返回
MOV R1 R0 LSL 3 ;将寄存器 R0 左移 3 位后 送到 R1
2 MVN 指令
MVN 指令的格式
MVN{ 条件 }{S} 目的寄存器,源操作数
MVN 指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加 到目的寄存器。与 MOV 指令不同之 是在 送之前按位被取反了,即把一个被取反的 值传 送到目的寄存器中。其中 S 决定指令的操作是否影响 CPSR 中条件 志位的 ,当没有 S 指令不更新 CPSR 中条件 志位的
指令示例:
MVN R0 ,# 0 ;将立即数 0 取反 送到寄存器 R0 中,完成后 R0=-1
3 CMP 指令
CMP 指令的格式
CMP{ 条件 } 操作数 1 ,操作数 2
CMP 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数 行比 ,同 更新 CPSR 中条件 志位的 指令 行一次减法运算,但不存 储结 果,只更改条件 志位。 志位表示的是操作数 1 与操作数 2 ( 大、小、相等 ) ,例如,当操作数 1 大于操作操作数 2 此后的有 GT 的指令将可以 行。
指令示例:
CMP R1 R0 ;将寄存器 R1 与寄存器 R0 相减,并根据 CPSR 志位
CMP R1 ,# 100 ;将寄存器 R1 与立即数 100 相减,并根据 CPSR 志位
4 CMN 指令
CMN 指令的格式
CMN{ 条件 } 操作数 1 ,操作数 2
CMN 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后 行比 ,同 更新 CPSR 中条件 志位的 指令 实际 完成操作数 1 和操作数 2 相加,并根据 果更改条件 志位。
指令示例:
CMN R1 R0 ;将寄存器 R1 与寄存器 R0 相加, 并根据 CPSR 志位
CMN R1 ,# 100 ;将寄存器 R1 与立即数 100 相加,并根据 CPSR 志位
5 TST 指令
TST 指令的格式
TST{ 条件 } 操作数 1 ,操作数 2
TST 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数 行按位的与运算,并根据运算 果更新 CPSR 中条件 志位的 。操作数 1 是要 测试 的数据,而操作数 2 是一个位掩 指令一般用来 检测 是否 置了特定的位。
指令示例:
TST R1 ,#% 1 ;用于 测试 在寄存器 R1 中是否 置了最低位(%表示二 制数)
TST R1 ,# 0xffe ;将寄存器 R1 与立即数 0xffe 按位与,并根据 CPSR 志位
6 TEQ 指令
TEQ 指令的格式
TEQ{ 条件 } 操作数 1 ,操作数 2
TEQ 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数 行按位的异或运算,并根据运算 果更新 CPSR 中条件 志位的 指令通常用于比 操作数 1 和操作数 2 是否相等。
指令示例:
TEQ R1 R2 ;将寄存器 R1 与寄存器 R2 按位异或,并根据 CPSR 志位
7 ADD 指令
ADD 指令的格式
ADD{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
ADD 指令用于把两个操作数相加,并将 果存放到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。
指令示例:
ADD R0 R1 R2 R0 = R1 + R2
ADD R0 R1 #256 R0 = R1 + 256
ADD R0 R2 R3 LSL#1 R0 = R2 + (R3 << 1)
8 ADC 指令
ADC 指令的格式
ADC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
ADC 指令用于把两个操作数相加,再加上 CPSR 中的 C 条件 志位的 ,并将 果存放到目的寄存器中。它使用一个 志位, 这样 就可以做比 32 位大的数的加法,注意不要忘 记设 S 来更改 志。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。
以下指令序列完成两个 128 位数的加法,第一个数由高到低存放在寄存器 R7 R4 ,第二个数由高到低存放在寄存器 R11 R8 ,运算 果由高到低存放在寄存器 R3 R0
ADDS R0 R4 R8 加低端的字
ADCS R1 R5 R9 加第二个字, 带进
ADCS R2 R6 R10 加第三个字, 带进
ADC R3 R7 R11 加第四个字, 带进
9 SUB 指令
SUB 指令的格式
SUB{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
SUB 指令用于把操作数 1 减去操作数 2 ,并将 果存放到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令可用于有符号数或无符号数的减法运算。
指令示例:
SUB R0 R1 R2 R0 = R1 - R2
SUB R0 R1 #256 R0 = R1 - 256
SUB R0 R2 R3 LSL#1 R0 = R2 - (R3 << 1)
10 SBC 指令
SBC 指令的格式
SBC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
SBC 指令用于把操作数 1 减去操作数 2 ,再减去 CPSR 中的 C 条件 志位的反 ,并将 果存放到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令使用 志来表示借位, 这样 就可以做大于 32 位的减法,注意不要忘 记设 S 来更改 志。 指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBS R0 R1 R2 R0 = R1 - R2 - C ,并根据 CPSR 志位
11 RSB 指令
RSB 指令的格式
RSB{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
RSB 指令称 逆向减法指令,用于把操作数 2 减去操作数 1 ,并将 果存放到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令可用于有符号数或无符号数的减法运算。
指令示例:
RSB R0 R1 R2 R0 = R2 – R1
RSB R0 R1 #256 R0 = 256 – R1
RSB R0 R2 R3 LSL#1 R0 = (R3 << 1) - R2
12 RSC 指令
RSC 指令的格式
RSC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
RSC 指令用于把操作数 2 减去操作数 1 ,再减去 CPSR 中的 C 条件 志位的反 ,并将 果存放到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令使用 志来表示借位, 这样 就可以做大于 32 位的减法,注意不要忘 记设 S 来更改 志。 指令可用于有符号数或无符号数的减法运算。
指令示例:
RSC R0 R1 R2 R0 = R2 – R1 - C
13 AND 指令
AND 指令的格式
AND{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
AND 指令用于在两个操作数上 逻辑 与运算,并把 果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令常用于屏蔽操作数 1 的某些位。
指令示例:
AND R0 R0 ,# 3 指令保持 R0 0 1 位,其余位清零。
14 ORR 指令
ORR 指令的格式
ORR{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
ORR 指令用于在两个操作数上 逻辑 或运算,并把 果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令常用 置操作数 1 的某些位。
指令示例:
ORR R0 R0 ,# 3 指令 R0 0 1 位,其余位保持不
15 EOR 指令
EOR 指令的格式
EOR{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
EOR 指令用于在两个操作数上 逻辑 异或运算,并把 果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。 指令常用于反 操作数 1 的某些位。
指令示例:
EOR R0 R0 ,# 3 指令反 R0 0 1 位,其余位保持不
16 BIC 指令
BIC 指令的格式
BIC{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
BIC 指令用于清除操作数 1 的某些位,并把 果放置到目的寄存器中。操作数 1 是一个寄存器,操作数 2 可以是一个寄存器,被移位的寄存器,或一个立即数。操作数 2 32 位的掩 ,如果在掩 置了某一位, 清除 一位。未 置的掩 位保持不
指令示例:
BIC R0 R0 ,#% 1011 指令清除 R0 中的位 0 1 、和 3 ,其余的位保持不

3.3.3 乘法指令与乘加指令
ARM 理器支持的乘法指令与乘加指令共有 6 条,可分 运算 32 位和运算 64 位两 ,与前面的数据 理指令不同,指令中的所有操作数、目的寄存器必 须为 通用寄存器,不能 操作数使用立即数或被移位的寄存器,同 ,目的寄存器和操作数 1 是不同的寄存器。
乘法指令与乘加指令共有以下 6 条:
— MUL 32 位乘法指令
— MLA 32 位乘加指令
— SMULL 64 位有符号数乘法指令
— SMLAL 64 位有符号数乘加指令
— UMULL 64 位无符号数乘法指令
— UMLAL 64 位无符号数乘加指令
1 MUL 指令
MUL 指令的格式
MUL{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2
MUL 指令完成将操作数 1 与操作数 2 的乘法运算,并把 果放置到目的寄存器中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的有符号数或无符号数。
指令示例:
MUL R0 R1 R2 R0 = R1 × R2
MULS R0 R1 R2 R0 = R1 × R2 ,同 时设 CPSR 中的相 条件 志位
2 MLA 指令
MLA 指令的格式
MLA{ 条件 }{S} 目的寄存器,操作数 1 ,操作数 2 ,操作数 3
MLA 指令完成将操作数 1 与操作数 2 的乘法运算,再将乘 加上操作数 3 ,并把 果放置到目的寄存器中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的有符号数或无符号数。
指令示例:
MLA R0 R1 R2 R3 R0 = R1 × R2 + R3
MLAS R0 R1 R2 R3 R0 = R1 × R2 + R3 ,同 时设 CPSR 中的相 条件 志位
3 SMULL 指令
SMULL 指令的格式
SMULL{ 条件 }{S} 目的寄存器 Low ,目的寄存器低 High ,操作数 1 ,操作数 2
SMULL 指令完成将操作数 1 与操作数 2 的乘法运算,并把 果的低 32 位放置到目的寄存器 Low 中, 果的高 32 位放置到目的寄存器 High 中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的有符号数。
指令示例:
SMULL R0 R1 R2 R3 R0 = R2 × R3 )的低 32
R1 = R2 × R3 )的高 32
4 SMLAL 指令
SMLAL 指令的格式
SMLAL{ 条件 }{S} 目的寄存器 Low ,目的寄存器低 High ,操作数 1 ,操作数 2
SMLAL 指令完成将操作数 1 与操作数 2 的乘法运算,并把 果的低 32 位同目的寄存器 Low 中的 相加后又放置到目的寄存器 Low 中, 果的高 32 位同目的寄存器 High 中的 相加后又放置到目的寄存器 High 中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的有符号数。
于目的寄存器 Low ,在指令 行前存放 64 位加数的低 32 位,指令 行后存放 果的低 32 位。
于目的寄存器 High ,在指令 行前存放 64 位加数的高 32 位,指令 行后存放 果的高 32 位。
指令示例:
SMLAL R0 R1 R2 R3 R0 = R2 × R3 )的低 32 R0
R1 = R2 × R3 )的高 32 R1
5 UMULL 指令
UMULL 指令的格式
UMULL{ 条件 }{S} 目的寄存器 Low ,目的寄存器低 High ,操作数 1 ,操作数 2
UMULL 指令完成将操作数 1 与操作数 2 的乘法运算,并把 果的低 32 位放置到目的寄存器 Low 中, 果的高 32 位放置到目的寄存器 High 中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的无符号数。
指令示例:
UMULL R0 R1 R2 R3 R0 = R2 × R3 )的低 32
R1 = R2 × R3 )的高 32
6 UMLAL 指令
UMLAL 指令的格式
UMLAL{ 条件 }{S} 目的寄存器 Low ,目的寄存器低 High ,操作数 1 ,操作数 2
UMLAL 指令完成将操作数 1 与操作数 2 的乘法运算,并把 果的低 32 位同目的寄存器 Low 中的 相加后又放置到目的寄存器 Low 中, 果的高 32 位同目的寄存器 High 中的 相加后又放置到目的寄存器 High 中,同 可以根据运算 CPSR 中相 的条件 志位。其中,操作数 1 和操作数 2 32 位的无符号数。
于目的寄存器 Low ,在指令 行前存放 64 位加数的低 32 位,指令 行后存放 果的低 32 位。
于目的寄存器 High ,在指令 行前存放 64 位加数的高 32 位,指令 行后存放 果的高 32 位。
指令示例:
UMLAL R0 R1 R2 R3 R0 = R2 × R3 )的低 32 R0
R1 = R2 × R3 )的高 32 R1
3.3.4
程序状 寄存器 访问 指令
ARM 理器支持程序状 寄存器 访问 指令,用于在程序状 寄存器和通用寄存器之 间传 送数据,程序状 寄存器 访问 指令包括以下两条:
— MRS 程序状 寄存器到通用寄存器的数据 送指令
— MSR 通用寄存器到程序状 寄存器的数据 送指令
1 MRS 指令
MRS 指令的格式
MRS{ 条件 } 通用寄存器,程序状 寄存器( CPSR SPSR
MRS 指令用于将程序状 寄存器的内容 送到通用寄存器中。 指令一般用在以下几 情况:
当需要改 程序状 寄存器的内容 ,可用 MRS 将程序状 寄存器的内容 入通用寄存器,修改后再写回程序状 寄存器。
当在异常 理或 程切 换时 ,需要保存程序状 寄存器的 ,可先用 指令 出程序状 寄存器的 ,然后保存。
指令示例:
MRS R0 CPSR CPSR 的内容到 R0
MRS R0 SPSR SPSR 的内容到 R0
2 MSR 指令
MSR 指令的格式
MSR{ 条件 } 程序状 寄存器( CPSR SPSR _< > ,操作数
MSR 指令用于将操作数的内容 送到程序状 寄存器的特定域中。其中,操作数可以 通用寄存器或立即数。 < > 用于 置程序状 寄存器中需要操作的位, 32 位的程序状 寄存器可分 4 个域:
[31 24] 条件 志位域,用 f 表示;
[23 16] 位域,用 s 表示;
[15 8] 为扩 展位域,用 x 表示;
[7 0] 控制位域,用 c 表示;
指令通常用于恢 或改 程序状 寄存器的内容,在使用 ,一般要在 MSR 指令中指明将要操作的域。
指令示例:
MSR CPSR R0 R0 的内容到 CPSR
MSR SPSR R0 R0 的内容到 SPSR
MSR CPSR_c R0 R0 的内容到 SPSR ,但 仅仅 修改 CPSR 中的控制位域

3.3.5 / 指令
ARM 理器支持加 / 指令用于在寄存器和存 器之 间传 送数据,加 指令用于将存 器中的数据 送到寄存器,存 指令 完成相反的操作。常用的加 指令如下:
— LDR 字数据加 指令
— LDRB 数据加 指令
— LDRH 半字数据加 指令
— STR 字数据存 指令
— STRB 数据存 指令
— STRH 半字数据存 指令
1 LDR 指令
LDR 指令的格式
LDR{ 条件 } 目的寄存器, < 器地址 >
LDR 指令用于从存 器中将一个 32 位的字数据 送到目的寄存器中。 指令通常用于从存 器中 32 位的字数据到通用寄存器,然后 数据 理。当程序 数器 PC 目的寄存器 ,指令从存 器中 取的字数据被当作目的地址,从而可以 实现 程序流程的跳 指令在程序 设计 中比 常用,且 址方式灵活多 请读 真掌握。
指令示例:
LDR R0 [R1] ;将存 器地址 R1 的字数据 入寄存器 R0
LDR R0 [R1 R2] ;将存 器地址 R1+R2 的字数据 入寄存器 R0
LDR R0 [R1 ,# 8] ;将存 器地址 R1+8 的字数据 入寄存器 R0
LDR R0 [R1 R2] ;将存 器地址 R1+R2 的字数据 入寄存器 R0 ,并将新地址 R1 R2 写入 R1
LDR R0 [R1 ,# 8] ;将存 器地址 R1+8 的字数据 入寄存器 R0 ,并将新地址 R1 8 写入 R1
LDR R0 [R1] R2 ;将存 器地址 R1 的字数据 入寄存器 R0 ,并将新地址 R1 R2 写入 R1
LDR R0 [R1 R2 LSL 2] ;将存 器地址 R1 R2×4 的字数据 入寄存器 R0 ,并将新地址 R1 R2×4 写入 R1
LDR R0 [R1] R2 LSL 2 ;将存 器地址 R1 的字数据 入寄存器 R0 ,并将新地址 R1 R2×4 写入 R1
2 LDRB 指令
LDRB 指令的格式
LDR{ 条件 }B 目的寄存器, < 器地址 >
LDRB 指令用于从存 器中将一个 8 位的字 数据 送到目的寄存器中,同 将寄存器的高 24 位清零。 指令通常用于从存 器中 8 位的字 数据到通用寄存器,然后 数据 理。当程序 数器 PC 目的寄存器 ,指令从存 器中 取的字数据被当作目的地址,从而可以 实现 程序流程的跳
指令示例:
LDRB R0 [R1] ;将存 器地址 R1 的字 数据 入寄存器 R0 ,并将 R0 的高 24 位清零。
LDRB R0 [R1 ,# 8] ;将存 器地址 R1 8 的字 数据 入寄存器 R0 ,并将 R0 的高 24 位清零。
3 LDRH 指令
LDRH 指令的格式
LDR{ 条件 }H 目的寄存器, < 器地址 >
LDRH 指令用于从存 器中将一个 16 位的半字数据 送到目的寄存器中,同 将寄存器的高 16 位清零。 指令通常用于从存 器中 16 位的半字数据到通用寄存器,然后 数据 理。当程序 数器 PC 目的寄存器 ,指令从存 器中 取的字数据 被当作目的地址,从而可以 实现 程序流程的跳
指令示例:
LDRH R0 [R1] ;将存 器地址 R1 的半字数据 入寄存器 R0 ,并将 R0 的高 16 位清零。
LDRH R0 [R1 ,# 8] ;将存 器地址 R1 8 的半字数据 入寄存器 R0 ,并将 R0 的高 16 位清零。
LDRH R0 [R1 R2] ;将存 器地址 R1 R2 的半字数据 入寄存器 R0 ,并将 R0 的高 16 位清零。
4 STR 指令
STR 指令的格式
STR{ 条件 } 源寄存器, < 器地址 >
STR 指令用于从源寄存器中将一个 32 位的字数据 送到存 器中。 指令在程序 设计 中比 常用,且 址方式灵活多 ,使用方式可参考指令 LDR
指令示例:
STR R0 [R1] ,# 8 ;将 R0 中的字数据写入以 R1 地址的存 器中,并将新地址 R1 8 写入 R1
STR R0 [R1 ,# 8] ;将 R0 中的字数据写入以 R1 8 地址的存 器中。
5 STRB 指令
STRB 指令的格式
STR{ 条件 }B 源寄存器, < 器地址 >
STRB 指令用于从源寄存器中将一个 8 位的字 数据 送到存 器中。 数据 源寄存器中的 8 位。
指令示例:
STRB R0 [R1] ;将寄存器 R0 中的字 数据写入以 R1 地址的存 器中。
STRB R0 [R1 ,# 8] ;将寄存器 R0 中的字 数据写入以 R1 8 地址的存 器中。
6 STRH 指令
STRH 指令的格式
STR{ 条件 }H 源寄存器, < 器地址 >
STRH 指令用于从源寄存器中将一个 16 位的半字数据 送到存 器中。 半字数据 源寄存器中的低 16 位。
指令示例:
STRH R0 [R1] ;将寄存器 R0 中的半字数据写入以 R1 地址的存 器中。
STRH R0 [R1 ,# 8] ;将寄存器 R0 中的半字数据写入以 R1 8 地址的存 器中。
3.3.6 批量数据加 / 指令
ARM 理器所支持批量数据加 / 指令可以一次在一片 连续 的存 元和多个寄存器之 间传 送数据,批量加 指令用于将一片 连续 的存 器中的数据 送到多个寄存器,批量数据存 指令 完成相反的操作。常用的加 指令如下:
— LDM 批量数据加 指令
— STM 批量数据存 指令
LDM (或 STM )指令
LDM (或 STM )指令的格式
LDM (或 STM { 条件 }{ } 基址寄存器 { } ,寄存器列表 { }
LDM (或 STM )指令用于从由基址寄存器所指示的一片 连续 器到寄存器列表所指示的多个寄存器之 间传 送数据, 指令的常 用途是将多个寄存器的内容入 或出 。其中, { } 以下几 情况:
IA 送后地址加 1
IB 送前地址加 1
DA 送后地址减 1
DB 送前地址减 1
FD 满递 减堆
ED 减堆
FA 满递 增堆
EA 增堆
{ } ,若 当数据 送完 之后,将最后的地址写入基址寄存器,否 基址寄存器的内容不改
基址寄存器不允 许为 R15 ,寄存器列表可以 R0 R15 的任意 合。
{ } ,当指令 LDM 且寄存器列表中包含 R15 缀时 表示:除了正常的数据 送之外, SPSR 制到 CPSR 。同 缀还 表示 入或 出的是用 模式下的寄存器,而不是当前模式下的寄存器。
指令示例:
STMFD R13! {R0 R4-R12 LR} ;将寄存器列表中的寄存器( R0 R4 R12 LR )存入堆
LDMFD R13! {R0 R4-R12 PC} ;将堆 内容恢 到寄存器( R0 R4 R12 LR )。

3.3.7 数据交 指令
ARM 理器所支持数据交 指令能在存 器和寄存器之 数据。数据交 指令有如下两条:
— SWP 字数据交 指令
— SWPB 数据交 指令
1 SWP 指令
SWP 指令的格式
SWP{ 条件 } 目的寄存器,源寄存器 1 [ 源寄存器 2]
SWP 指令用于将源寄存器 2 所指向的存 器中的字数据 送到目的寄存器中,同 将源寄存器 1 中的字数据 送到源寄存器 2 所指向的存 器中。 然,当源寄存器 1 和目的寄存器 同一个寄存器 ,指令交 换该 寄存器和存 器的内容。
指令示例:
SWP R0 R1 [R2] ;将 R2 所指向的存 器中的字数据 送到 R0 ,同 R1 中的字数据 送到 R2 所指向的存 储单 元。
SWP R0 R0 [R1] 指令完成将 R1 所指向的存 器中的字数据与 R0 中的字数据交
2 SWPB 指令
SWPB 指令的格式
SWP{ 条件 }B 目的寄存器,源寄存器 1 [ 源寄存器 2]
SWPB 指令用于将源寄存器 2 所指向的存 器中的字 数据 送到目的寄存器中,目的寄存器的高 24 清零,同 将源寄存器 1 中的字 数据 送到源寄存器 2 所指向的存 器中。 然,当源寄存器 1 和目的寄存器 同一个寄存器 ,指令交 换该 寄存器和存 器的内容。
指令示例:
SWPB R0 R1 [R2] ;将 R2 所指向的存 器中的字 数据 送到 R0 R0 的高 24 位清零,同 R1 中的低 8 位数据 送到 R2 所指向的存 储单 元。
SWPB R0 R0 [R1] 指令完成将 R1 所指向的存 器中的字 数据与 R0 中的低 8 位数据交
3.3.8
移位指令(操作)
ARM 理器内嵌的桶型移位器( Barrel Shifter ),支持数据的各 移位操作,移位操作在 ARM 指令集中不作 为单 独的指令使用,它只能作 指令格式中是一个字段,在 汇编语 言中表示 指令中的 选项 。例如,数据 理指令的第二个操作数 寄存器 ,就可以加入移位操作 选项对 行各 移位操作。移位操作包括如下 6 种类 型, ASL LSL 是等价的,可以自由互
— LSL 逻辑 左移
— ASL 左移
— LSR 逻辑 右移
— ASR 右移
— ROR 右移
— RRX 带扩 展的循 右移
1 LSL (或 ASL )操作
LSL (或 ASL )操作的格式
通用寄存器, LSL (或 ASL 操作数
LSL (或 ASL )可完成 通用寄存器中的内容 逻辑 (或算 )的左移操作,按操作数所指定的数量向左移位,低位用零来填充。其中,操作数可以是通用寄存器,也可以是立即数( 0 31 )。
操作示例:
MOV R0, R1, LSL#2 ;将 R1 中的内容左移两位后 送到 R0 中。
2 LSR 操作
LSR 操作的格式
通用寄存器, LSR 操作数
LSR 可完成 通用寄存器中的内容 行右移的操作,按操作数所指定 的数量向右移位,左端用零来填充。其中,操作数可以是通用寄存器,也可以是立即数( 0 31 )。
操作示例:
MOV R0, R1, LSR#2 ;将 R1 中的内容右移两位后 送到 R0 中,左端用零来填充。
3 ASR 操作
ASR 操作的格式
通用寄存器, ASR 操作数
ASR 可完成 通用寄存器中的内容 行右移的操作,按操作数所指定的数量向右移位,左端用第 31 位的 来填充。其中,操作数可以是通用寄存器,也可以是立即数( 0 31 )。
操作示例:
MOV R0, R1, ASR#2 ;将 R1 中的内容右移两位后 送到 R0 中,左端用第 31 位的 来填充。
4 ROR 操作
ROR 操作的格式
通用寄存器, ROR 操作数
ROR 可完成 通用寄存器中的内容 行循 右移的操作,按操作数所指定的数量向右循 移位,左端用右端移出的位来填充。其中,操作数可以是通用寄存器,也可以是立即数( 0 31 )。 然,当 32 位的循 右移操作 ,通用寄存器中的 不改
操作示例:
MOV R0, R1, ROR#2 ;将 R1 中的内容循 右移两位后 送到 R0 中。
5 RRX 操作
RRX 操作的格式
通用寄存器, RRX 操作数
RRX 可完成 通用寄存器中的内容 带扩 展的循 右移的操作,按操作数所指定的数量向右循 移位,左端用 志位 C 来填充。其中,操作数可以是通用寄存器,也可以是立即数( 0 31 )。
操作示例:
MOV R0, R1, RRX#2 ;将 R1 中的内容 带扩 展的循 右移两位后 送到 R0 中。

3.3.9 协处 理器指令
ARM 理器可支持多达 16 协处 理器,用于各 种协处 理操作,在程序 行的 程中, 协处 理器只 针对 自身的 协处 理指令,忽略 ARM 理器和其他 协处 理器的指令。
ARM 协处 理器指令主要用于 ARM 理器初始化 ARM 协处 理器的数据 理操作,以及在 ARM 理器的寄存器和 协处 理器的寄存器之 间传 送数据,和在 ARM 协处 理器的寄存器和存 器之 间传 送数据。 ARM 协处 理器指令包括以下 5 条:
— CDP 协处 理器数操作指令
— LDC 协处 理器数据加 指令
— STC 协处 理器数据存 指令
— MCR ARM 理器寄存器到 协处 理器寄存器的数据 送指令
— MRC 协处 理器寄存器到 ARM 理器寄存器的数据 送指令
1 CDP 指令
CDP 指令的格式
CDP{ 条件 } 协处 理器 编码 协处 理器操作 1 ,目的寄存器,源寄存器 1 ,源寄存器 2 协处 理器操作 2
CDP 指令用于 ARM 理器通知 ARM 协处 理器 行特定的操作 , 协处 理器不能成功完成特定的操作, 则产 生未定 指令异常。其中 协处 理器操作 1 协处 理器操作 2 为协处 理器将要 行的操作,目的寄存器和源寄存器均 为协处 理器的寄存器,指令不 ARM 理器的寄存器和存 器。
指令示例:
CDP P3 2 C12 C10 C3 4 指令完成 协处 理器 P3 的初始化
2 LDC 指令
LDC 指令的格式
LDC{ 条件 }{L} 协处 理器 编码 , 目的寄存器, [ 源寄存器 ]
LDC 指令用于将源寄存器所指向的存 器中的字数据 送到目的寄存器中,若 协处 理器不能成功完成 送操作, 则产 生未定 指令异常。其中, {L} 选项 表示指令 为长读 取操作,如用于双精度数据的 传输
指令示例:
LDC P3 C4 [R0] ;将 ARM 理器的寄存器 R0 所指向的存 器中的字数据 送到 协处 理器 P3 的寄存器 C4 中。
3 STC 指令
STC 指令的格式
STC{ 条件 }{L} 协处 理器 编码 , 源寄存器, [ 目的寄存器 ]
STC 指令用于将源寄存器中的字数据 送到目的寄存器所指向的存 器中,若 协处 理器不能成功完成 送操作, 则产 生未定 指令异常。其中, {L} 选项 表示指令 为长读 取操作,如用于双精度数据的 传输
指令示例:
STC P3 C4 [R0] ;将 协处 理器 P3 的寄存器 C4 中的字数据 送到 ARM 理器的寄存器 R0 所指向的存 器中。
4 MCR 指令
MCR 指令的格式
MCR{ 条件 } 协处 理器 编码 协处 理器操作 1 ,源寄存器,目的寄存器 1 ,目的寄存器 2 协处 理器操作 2
MCR 指令用于将 ARM 理器寄存器中的数据 送到 协处 理器寄存器中 , 协处 理器不能成功完 成操作, 则产 生未定 指令异常。其中 协处 理器操作 1 协处 理器操作 2 为协处 理器将要 行的操作,源寄存器 ARM 理器的寄存器,目的寄存器 1 和目的寄存器 2 为协处 理器的寄存器。
指令示例:
MCR P3 3 R0 C4 C5 6 指令将 ARM 理器寄存器 R0 中的数据 送到 协处 理器 P3 的寄存器 C4 C5 中。
5 MRC 指令
MRC 指令的格式
MRC{ 条件 } 协处 理器 编码 协处 理器操作 1 ,目的寄存器,源寄存器 1 ,源寄存器 2 协处 理器操作 2
MRC 指令用于将 协处 理器寄存器中的数据 送到 ARM 理器寄存 器中 , 协处 理器不能成功完成操作, 则产 生未定 指令异常。其中 协处 理器操作 1 协处 理器操作 2 为协处 理器将要 行的操作,目的寄存器 ARM 理器的寄存器,源寄存器 1 和源寄存器 2 为协处 理器的寄存器。
指令示例:
MRC P3 3 R0 C4 C5 6 指令将 协处 理器 P3 的寄存器中的数据 送到 ARM 理器寄存器中。

3.3.10 异常 生指令
ARM 理器所支持的异常指令有如下两条:
— SWI 件中断指令
— BKPT 断点中断指令
1 SWI 指令
SWI 指令的格式
SWI{ 条件 } 24 位的立即数
SWI 指令用于 件中断,以便用 程序能 用操作系 的系 例程。操作系 SWI 的异常 理程序中提供相 的系 ,指令中 24 位的立即数指定用 程序 用系 例程的 型,相 参数通 通用寄存器 传递 ,当指令中 24 位的立即数被忽略 ,用 程序 用系 例程的 型由通用寄存器 R0 的内容决定,同 ,参数通 其他通用寄存器 传递
指令示例:
SWI 0x02 指令 用操作系 统编 号位 02 的系 例程。
2 BKPT 指令
BKPT 指令的格式
BKPT 16 位的立即数
BKPT 指令 件断点中断,可用于程序的 调试
3.4 Thumb
指令及
兼容数据 总线宽 16 位的 用系 ARM 体系 构除了支持 行效率很高的 32 ARM 指令集以外,同 支持 16 位的 Thumb 指令集。 Thumb 指令集是 ARM 指令集的一个子集,允 指令 编码为 16 位的 度。与等价的 32 位代 相比 Thumb 指令集在保留 32 码优势 的同 ,大大的 省了系 的存
所有的 Thumb 指令都有 对应 ARM 指令,而且 Thumb 程模型也 对应 ARM 程模型,在 用程序的 程中,只要遵循一定 用的 规则 Thumb 子程序和 ARM 子程序就可以互相 用。当 理器在 ARM 程序段 ,称 ARM 理器 ARM 工作状 ,当 理器在 Thumb 程序段 ,称 ARM 理器 Thumb 工作状
ARM 指令集相比 Thumb 指令集中的数据 理指令的操作数仍然是 32 位,指令地址也 32 位,但 Thumb 指令集 为实现 16 位的指令 度,舍弃了 ARM 指令集的一些特性,如大多数的 Thumb 指令是无条件 行的,而几乎所有的 ARM 指令都是有条件 行的;大多数的 Thumb 数据 理指令的目的寄存器与其中一个源寄存器相同。
由于 Thumb 指令的 16 位,即只用 ARM 指令一半的位数来 实现 的功能,所以,要 实现 特定的程序功能,所需的 Thumb 指令的条数 ARM 指令多。在一般的情况下, Thumb 指令与 ARM 指令的 时间 效率和空 效率
— Thumb 所需的存 间约为 ARM 60 %~ 70
— Thumb 使用的指令数比 ARM 30 %~ 40
若使用 32 位的存 器, ARM Thumb 40
若使用 16 位的存 器, Thumb ARM 40 %~ 50
ARM 相比 ,使用 Thumb ,存 器的 功耗会降低 30
然, ARM 指令集和 Thumb 指令集各有其 点,若 的性能有 高要求, 使用 32 位的存 ARM 指令集,若 的成本及功耗有 高要求, 则应 使用 16 位的存 Thumb 指令集。当然,若两者 合使用,充分 发挥 其各自的 点,会取得更好的效果。

3.5 本章小
本章系 的介 ARM 指令集中的基本指令,以及各指令的 合及方法,由基本指令 可以派生出一些新的指令,但使用方法与基本指令 似。与常 的如 X86 体系 构的 汇编 指令相比 ARM 指令系 是从指令集本身, 是从 址方 式上,都相 对复杂 一些。
Thumb 指令集作 ARM 指令集的一个子集,其使用方法与 ARM 指令集 似,在此未作 详细 的描述,但 并不意味着 Thumb 指令集不如 ARM 指令集重要,事 上,他 各自有其自己的
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值