第4章 ARM7TDMI(-S)指令系统
… DATA_BUF
3. Thumb 数据处理指令
大多数Thumb 数据处理指令采用 2 地址格式,数据处理操作比 ARM 状态的更少,访问 寄存器R8~R15 受到一定限制。
Thumb 数据处理指令见表 4.12。
表 4.12 Thumb 数据处理指令
助记符 说明 操作 影响标志
MOV Rd,#expr 数据传送指令 Rd←expr,Rd 为 R0~R7 影响N、Z
MOV Rd,Rm 数据传送指令 Rd←Rm,Rd、Rm 均可为 R0~R15 Rd 和 Rm 均为 R0~R7 时,
影响N、Z,清零 C、V MVN Rd,Rm 数据非传送指令 Rd←(~Rm) ,Rd、Rm 均为 R0~R7 影响N、Z
NEG Rd,Rm 数据取负指令 Rd←(-Rm) ,Rd、Rm 均为 R0~R7 影响N、Z、C、V ADD Rd,Rn,Rm 加法运算指令 Rd←Rn+Rm,Rd、Rn、Rm 均为 R0~R7 影响N、Z、C、V ADD Rd,Rn,#expr3 加法运算指令 Rd←Rn+expr3,Rd、Rn 均为 R0~R7 影响N、Z、C、V ADD Rd,#expr8 加法运算指令 Rd←Rd+expr8,Rd 为 R0~R7 影响N、Z、C、V ADD Rd, Rm 加法运算指令 Rd←Rd+Rm,Rd、Rm 均可为 R0~R15 Rd 和 Rm 均为 R0~R7 时,
影响N、Z、C、V ADD Rd,Rp,#expr SP/PC 加法运算指令 Rd←SP+expr 或 PC+expr,Rd 为 R0~R7 无
- - 96 接上表
助记符 说明 操作 影响标志
ADD SP,#expr SP 加法运算指令 SP←SP+expr 无
SUB Rd,Rn,Rm 减法运算指令 Rd←Rn-Rm,Rd、Rn、Rm 均为 R0~R7 影响N、Z、C、V SUB Rd,Rn,#expr3 减法运算指令 Rd←Rn-expr3,Rd、Rn 均为 R0~R7 影响N、Z、C、V SUB Rd,#expr8 减法运算指令 Rd←Rd-expr8,Rd 为 R0~R7 影响N、Z、C、V
SUB SP,#expr SP 减法运算指令 SP←SP-expr 无
ADC Rd,Rm 带进位加法指令 Rd←Rd+Rm+ Carry,Rd、Rm 为 R0~R7 影响N、Z、C、V SBC Rd,Rm 带进位减法指令 Rd←Rd-Rm-(NOT)Carry,Rd、Rm 为 R0~R7 影响N、Z、C、V MUL Rd,Rm 乘法运算指令 Rd←Rd*Rm,Rd、Rm 为 R0~R7 影响N、Z AND Rd,Rm 逻辑与操作指令 Rd←Rd & Rm,Rd、Rm 为 R0~R7 影响N、Z ORR Rd,Rm 逻辑或操作指令 Rd←Rd | Rm,Rd、Rm 为 R0~R7 影响N、Z EOR Rd,Rm 逻辑异或操作指令 Rd←Rd ^ Rm,Rd、Rm 为 R0~R7 影响N、Z BIC Rd,Rm 位清除指令 Rd←Rd & (~Rm),Rd、Rm 为 R0~R7 影响N、Z ASR Rd,Rs 算术右移指令 Rd←Rd 算术右移 Rs 位,Rd、Rs 为 R0~R7 影响N、Z、C ASR Rd,Rm,#expr 算术右移指令 Rd←Rm 算术右移 expr 位,Rd、Rm 为 R0~R7 影响N、Z、C LSL Rd,Rs 逻辑左移指令 Rd←Rd << Rs,Rd、Rs 为 R0~R7 影响N、Z、C LSL Rd,Rm,#expr 逻辑左移指令 Rd←Rm << expr,Rd、Rm 为 R0~R7 影响N、Z、C LSR Rd,Rs 逻辑右移指令 Rd←Rd >> Rs,Rd、Rs 为 R0~R7 影响N、Z、C LSR Rd,Rm,#expr 逻辑右移指令 Rd←Rm >> expr,Rd、Rm 为 R0~R7 影响N、Z、C ROR Rd,Rs 循环右移指令 Rd←Rm 循环右移 Rs 位,Rd、Rs 为 R0~R7 影响N、Z、C CMP Rn,Rm 比较指令 状态标志←Rn-Rm,Rn、Rm 均可为 R0~R15 影响N、Z、C、V CMP Rn,#expr 比较指令 状态标志←Rn-expr,Rn 为 R0~R7 影响N、Z、C、V CMN Rn,Rm 负数比较指令 状态标志←Rn+Rm,Rn、Rm 为 R0~R7 影响N、Z、C、V TST Rn,Rm 位测试指令 状态标志←Rn & Rm,Rn、Rm 为 R0~R7 影响N、Z、C、V
数据传送指令
MOV——数据传送指令
MOV 指令将 8 位立即数或寄存器(operand2)传送到目标寄存器(Rd)。指令格式如下:
MOV Rd,#expr MOV Rd,Rm
其中: Rd 目标寄存器。MOV Rd,#expr 时,Rd 必须在 R0~R7 之间。
exper 8 位立即数,即 0~255。
Rm 源寄存器。为R0~R15。
指令编码格式(立即数转送):
指令编码格式(寄存器转送):
- - 97 条件码标志:
MOV Rd,#expr 指令会更新 N 和 Z 标志,对标志 C 和 V 无影响。而 MOV Rd,Rm 指 令,若Rd 或 Rm 是高寄存器(R8~R15),则标志不受影响,若 Rd 或 Rm 都是低寄存器(R0~
R7),则会更新标志 N 和 Z,且清除标志 C 和 V。
MOV 指令举例如下:
MOV R1,#0x10 ; R1=0x10 MOV R0,R8 ; R0=R8
MOV PC,LR ; PC=LR,子程序返回
MVN——数据非传送指令
MVN 指令将寄存器 Rm 按位取反后传送到目标寄存器(Rd)。指令格式如下:
MVN Rd,Rm
其中: Rd 目标寄存器。必须在 R0~R7 之间。
Rm 源寄存器。必须在R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N 和 Z 标志,对标志 C 和 V 无影响。
MVN 指令举例如下:
MVN R1,R2 ; 将R2 取反,结果存到 R1
NEG——数据取负指令
NEG 指令将寄存器 Rm 乘以-1 后传送到目标寄存器(Rd)。指令格式如下:
NEG Rd,Rm
其中: Rd 目标寄存器。必须在 R0~R7 之间。
Rm 源寄存器。必须在R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N、Z、C 和 V 标志。
NEG 指令举例如下:
NEG R1,R0 ; R1-R0
算术逻辑运算指令
ADD——加法运算指令
- - 98
ADD 指令将两个数据相加,结果保存到 Rd 寄存器。
低寄存器的 ADD 指令的指令格式如下:
ADD Rd,Rn, Rm ADD Rd,Rn,#expr3 ADD Rd,#expr8
其中: Rd 目标寄存器。必须在 R0~R7 之间。
Rn 第1 个操作数寄存器。必须在 R0~R7 之间。
Rm 第2 个操作数寄存器。必须在 R0~R7 之间。
expr3 3 位立即数,即 0~7。
expr8 8 位立即数,即 0~255。
指令编码格式(ADD Rd,Rn, Rm):
指令编码格式(ADD Rd,Rn,#expr3):
指令编码格式(ADD Rd,#expr8):
条件码标志:
指令会更新N、Z、C 和 V 标志。
高或低寄存器的 ADD 指令的指令格式如下:
ADD Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。
Rm 第二个操作数寄存器。
指令编码格式:
H1 用于指示Rd 是否为高寄存器。
H2 用于指示Rm 是否为高寄存器。
条件码标志:
若Rd 或 Rm 都是低寄存器(R0~R7),指令会更新 N、Z、C 和 V 标志。其它情况不影响 条件码标志。
PC 或 SP 相对偏移的 ADD 指令的指令格式如下:
ADD Rd,Rp,#expr
其中: Rd 目标寄存器。必须在 R0~R7 之间。
- - 99
Rp PC 或 SP,第一个操作数寄存器。
expr 立即数,在 0~1020 范围内。
指令编码格式(ADD Rd,PC,#expr):
指令编码格式(ADD Rd,SP,#expr):
条件码标志:
不影响条件码标志。
SP 操作的 ADD 指令的指令格式如下:
ADD SP,#expr
其中: SP 目标寄存器,也是第一个操作数寄存器。
expr 立即数,在-508~+508 之间的 4 的整数倍的数。
指令编码格式:
条件码标志:
不影响条件码标志。
ADD 指令举例如下:
ADD R1,R1,R0 ; R1=R1+R0 ADD R1,R1,#7 ; R1=R1+7 ADD R3, #200 ; R3=R3+200 ADD R3,R8 ; R3=R3+R8 ADD R1,SP,#1000 ; R1=SP+1000 ADD SP,#-500 ; SP=SP-500
SUB——减法运算指令
SUB 指令将两个数相减,结果保存到 Rd 中。
低寄存器的 SUB 指令的指令格式如下:
SUB Rd,Rn, Rm SUB Rd,Rn,#expr3 SUB Rd,#expr8
其中: Rd 目标寄存器,必须在 R0~R7 之间。
Rn 第1 个操作数寄存器,必须在 R0~R7 之间。
Rm 第2 个操作数寄存器,必须在 R0~R7 之间。
expr3 3 位立即数,即 0~7。
- - 100 expr8 8 位立即数,即 0~255。
指令编码格式(SUB Rd,Rn, Rm):
指令编码格式(SUB Rd,Rn,#expr3):
指令编码格式(SUB Rd,#expr8):
条件码标志:
指令会更新N、Z、C 和 V 标志。
SP 操作的 SUB 指令的指令格式如下:
SUB SP,#expr
其中: SP 目标寄存器,也是第一个操作数寄存器。
expr 立即数,在-508~+508 之间的 4 的整数倍的数 指令编码格式:
条件码标志:
不影响条件码标志。
SUB 指令举例如下:
SUB R0,R2,R1 ; R0=R2-R1 SUB R2,R1,#1 ; R2=R1-1 SUB R6,#250 ; R6=R6-250 SUB SP,#380 ; SP=SP-380
ADC——带进位加法指令
ADC 指令将 Rm 的值与 Rd 的值相加,再加上 CPSR 中的 C 条件标志位,结果保存到 Rd 寄存器。指令格式如下:
ADC Rd, Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。必须在 R0~R7 之间。
Rm 第二个操作数寄存器。必须在R0~R7 之间。
指令编码格式:
- - 101 条件码标志:
指令会更新N、Z、C 和 V 标志。
ADC 指令举例如下:
ADD R0,R2
ADC R1,R3 ; 使用ADC 实现 64 位加法,(R1、R0)=(R1、R0)+(R3、R2)
SBC——带进位减法指令
SBC 指令用寄存器 Rd 减去 Rm,再减去 CPSR 中的 C 条件标志位的非(即若 C 标志清 零,则结果减去1),结果保存到 Rd 中。指令格式如下:
SBC Rd,Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。必须在 R0~R7 之间。
Rm 第二个操作数寄存器。必须在R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N、Z、C 和 V 标志。
SBC 指令举例如下:
SUB R0,R2
SBC R1,R3 ; 使用SBC 实现 64 位减法,(R1、R0)=(R1、R0)-(R3、R2)
MUL——乘法运算指令
MUL 指令用寄存器 Rd 乘以 Rm,结果保存到 Rd 中。指令格式如下:
MUL Rd,Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。必须在 R0~R7 之间。
Rm 第二个操作数寄存器,必须在R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N 和 Z 标志。
MUL 指令举例如下:
MUL R0,R1 ; R0=R0×R1
- - 102 AND——逻辑“与”操作指令
AND 指令将寄存器 Rd 的值与寄存器 Rm 的值按位作逻辑“与”操作,结果保存到 Rd 中。指令格式如下:
AND Rd,Rm
其中: Rd 目标寄存器,也是第一个操作数寄存器。必须在 R0~R7 之间。
Rm 第二个操作数寄存器。必须在R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N 和 Z 标志。
AND 指令举例如下:
MOV R1,#0x0F
AND R0,R1 ; R0=R0&R1
ORR——逻辑“或”操作指令
ORR 指令将寄存器 Rd 与寄存器 Rn 的值按位作逻辑“或”操作,结果保存到 Rd 中。指 令格式如下:
ORR Rd,Rm
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rm 第2 个操作数寄存器,必须在 R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N 和 Z 标志。
ORR 指令举例如下:
MOV R1,#0x03
ORR R0,R1 ; R0=R0 | R1
EOR——逻辑“异或”操作指令
EOR 指令将寄存器 Rd 的值与寄存器 Rn 的值按位作逻辑异或操作,结果保存到 Rd 中。
指令格式如下:
EOR Rd,Rm
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rm 第2 个操作数寄存器,必须在 R0~R7 之间。
指令编码格式:
- - 103 条件码标志:
指令会更新N 和 Z 标志。
EOR 指令举例如下:
MOV R2,#0xF0
EOR R3,R2 ; R3=R3 ^ R2
BIC——位清除指令
BIC 指令将寄存器 Rd 的值与寄存器 Rm 的值的反码按位作逻辑“与”操作,结果保存到 Rd 中。指令格式如下:
BIC Rd,Rm
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rm 第2 个操作数寄存器,必须在 R0~R7 之间。
指令编码格式:
条件码标志:
指令会更新N 和 Z 标志。
BIC 指令举例如下:
MOV R1,#0x80
BIC R3,R1 ; 将R1 的最高位清零,其它位不变
ASR——算术右移指令
ASR 指令将数据算术右移,将符号位拷贝到空位,移位结果保存到 Rd 中。指令格式如 下:
ASR Rd,Rs ASR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在R0~R7 之间。
Rm 立即数移位的源寄存器,必须在R0~R7 之间。
expr 立即数移位位数,值为 1~32。
指令编码格式(ASR Rd,Rs):
- - 104 指令编码格式(ASR Rd,Rm,#expr):
条件码标志:
指令会更新N、Z 和 C 标志(若移位位数为零,则不影响 C 标志)。
ASR 指令举例如下:
ASR R1,R2 ASR R3,R1,#2
若移位位数为32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位量大于 32,则 Rd 和标志 C 均被清零;若移位量为 0,则不影响 C 标志。
LSL——逻辑左移指令
LSR 指令将数据逻辑左移,空位清零,移位结果保存到 Rd 中。指令格式如下:
LSL Rd,Rs
LSL Rd,Rm,#expr
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在R0~R7 之间。
Rm 立即数移位的源寄存器,必须在R0~R7 之间。
expr 立即数移位位数,值为 1~31。
指令编码格式(LSL Rd,Rs):
指令编码格式(LSL Rd,Rm,#expr):
条件码标志:
指令会更新N、Z 和 C 标志(若移位位数为零,则不影响 C 标志)。
LSL 指令举例如下:
LSL R6,R7 LSL R1,R6,#2
若移位位数为32,则 Rd 清零,最后移出的位保留在标志 C 中;若移位位数大于 32,
则Rd 和标志 C 均被清零;若移位位数为 0,则不影响 C 标志。
LSR——逻辑右移指令
LSR 指令将数据逻辑右移,空位清零,移位结果保存到 Rd 中。指令格式如下:
- - 105 LSR Rd,Rs
LSR Rd,Rm,#expr
其中: Rd 目标寄存器,也是第 1 个操作数寄存器,必须在 R0~R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在R0~R7 之间。
Rs 寄存器控制移位中包含移位位数的寄存器,必须在R0~R7 之间。