ARM指令集2
来源:互联网 发布:linux top怎么退出 编辑:程序博客网 时间:2024/05/12 17:48
ARM工作模式:
管理模式
快速中断
中断
中止
未定义
系统
用户
异常和非异常
特权和非特权
ARM运行状态:
ARM状态:ARM指令,32bit,4字节对齐
Thumb状态:Thumb指令,16bit,2字节对齐
寄存器:
R0-R12:通用寄存器
R13(SP):存放栈顶指针
R14(LR):存放返回地址
R15(PC):存放取指的指令的地址
CPSR:程序状态寄存器
bit[4:0]:CPU的工作模式
bit[5]:CPU的运行状态
bit[6]:FIQ的禁止位
bit[7]:IRQ的禁止位
bit[31:28]:条件标志位NZCV
SPSR:5个,用于备份CPSR
跳转指令:PC
B:相对跳转,PC(跳转)=PC(当前)+/-偏移量(32M)
BL:相对跳转,PC(跳转)=PC(当前)+/-偏移量(32M)
要返回,MOVPC,LR PC=LR
BX:绝对跳转,4G,带状态切换,ARMThumb状态切换
BX R0
CPSR[5]=R0[0]
PC=R0& 0xFFFFFFFE
BLX:
数据处理指令可细分为4类:
数据传送指令(MOV、MVN)
算术运算指令(ADD、ADC、SUB、SBC、RSB、RSC)
位运算指令(AND、ORR、EOR、BIC)
比较指令(CMP、CMN、TST、TEQ)
数据处理指令的一般格式:
<opcode>{cond}{S} <Rd>, <Rn>, <shifter_operand>
<opcode>
{cond}
{S}
1.当目标寄存器不是PC时,根据目标寄存器的结果影响CPSR的NZCV条件标志位
MOVS R0,#2
由于目标寄存器不是PC,根据R0的结果影响NZCV
2.当目标寄存器是PC时,CPSR=SPSR
MOVS PC,LR //PC=LR,CPSR=SPSR
异常的返回
<Rd>:目标寄存器,寄存器
<Rn>:第一源操作数,只能是寄存器
<shifter_operand>:第二源操作数
ADD R0, R1, #1
MOVEQ R0, R2
SUBEQS R0, R1, R2, LSR #1
CMP R1, R3
操作数:
<Rn>:第一源操作数,只能是寄存器
<shifter_operand>:第二源操作数,共有11种
1.立即数:相当于常量,直接出现在指令中,不用存储在寄存器或存储器中
ADD R0,R1,#3 //R0=R1+3
2.寄存器:
ADD R0,R1,R2 //R0=R1+R2
3.寄存器移位:
1.<Rm>,LSL #<shift_imm>
ADD R0, R1, R2 LSL #1// R0=R1+(R2 << 1)
LSL逻辑左移:空出的低位用0填充
2.<Rm>,LSL <Rs>
ADD R0, R1, R2 LSL R3//R0=R1+(R2 << R3)
3.<Rm>,LSR #<shift_imm>
ADD R0, R1,R2 LSR #2 //R0=R1+(R2>>2)
LSR逻辑右移:空出的高位用0填充
4.<Rm>,LSR <Rs>
ADD R0, R1,R2 LSR R3 //R0=R1+(R2>>R3)
5.<Rm>,ASR #<shift_imm>
ASR算数右移:空出的高位用符号位填充
6.<Rm>,ASR <Rs>
7.<Rm>,ROR #<shift_imm>
ROR循环右移:移出的低位用于填充空出的高位
8.<Rm>,ROR <Rs>
9.<Rm>,RRX
RRX:扩展右移一位,将Rm寄存器的内容右移1位,空出的高位用原来CPSR的C位来填充,并将移出的1位填充CPSR的C位,只有RRX,不需要指定移位位数。
第一源操作数:寄存器
第二源操作数:11种
1.立即数
2.寄存器
3.寄存器移位(LSL,LSR,ASR,ROR,RRX)
1.LSL #shift
2.LSL Rs
空出的低位用0填充
3.LSR #shift
4.LSR Rs
空出的高位用0填充
5.ASR#shift
6.ASRRs
空出的高位用符号位填充
7.ROR#shift
8.RORRs
循环右移,将移出的低位填充空出的高位
9.RRX
扩展右移一位,将Rm寄存器的内容右移1位,空出的高位用原来CPSR的C位来填充,并将移出的1位填充CPSR的C位,只有RRX,不需要指定移位位数。
CMP R1,#0x04800000 32bit
找到8bit立即数,然后将8bit立即数扩展为32bit,再将该32bit的数采用循环右移的方式进行移位,移2X(#rot)次,最终得到0x4800000
将0x12扩展为32bit数,高位全用0填充,然后将其循环右移2X5=10次,即得到立即数0x4800000
5 0x12
6 0x48
如果找到的组合不唯一,取循环右移次数少的那组
8位图立即数
合法立即数的判定?
1.0-0xFF就是合法立即数
2.立即数中1的个数大于8的一定不合法
3.从两个方向看1的间距大于8,非法
数据传送指令MOV
指令格式:
MOV{cond}{S} <Rd>, <shifter_operand>
shifter_operand:立即数(8位图)、寄存器、寄存器移位
功能:Rd=<shifter_operand>
示例:
MOVEQ R0, #0x80 //EQ , R0=0x80
MOVS PC, LR
//S,目标寄存器PC,
//PC=LR,CPSR=SPSR异常返回
MOVEQS R0,R1
//EQ,R0=R1,R0的结果影响CPSR的NZCV
N= R0[31]
Z= if R0== 0 then 1 else 0
C= shifter_carry_out,
不影响V
MOV R3, R4, LSL #2 //R3=(R4<<2)
MOV R0, R0
MOV PC, R14 //PC=R14
NZCV:
N:运算结果为负值的标志位
N=1,负值
N=0,正值
Z:运算结果为0的标志位
Z=1,结果0
Z=0,结果为非0
数据取反传送指令:MVN
指令格式:
MVN{cond}{S} <Rd>, <shifter_operand>
shifter_operand:立即数(8位图)、寄存器、寄存器移位
功能:Rd=<shifter_operand>按位取反
示例
MVNEQ R0, #0x80
//EQ,将0x80按位取反,R0=0xFFFFFF7F
MVNS PC, R0
//PC=R0按位取反,S,PC,CPSR=SPSR
MVNEQS R0,R1
//EQ,R0=R1按位取反,S,R0的结果影响NZCV
N= R0[31]
Z= if R0 == 0 then 1 else 0
C= shifter_carry_out,
不影响V
MVN R3, R4, LSL #2
//R3=(R4<<2)按位取反
MOV R0,#0x00 //R0=0x0
MVN R0,#0x00 //R0=0xFFFFFFFF
MOV R0,#0xffffff00 //不合法
MVN R0, #0x000000FF //R0=(0x000000FF)按位取反
MOV
MVN
没有第一源操作数
S:
PC,CPSR=SPSR
不是PC,根据结果影响NZCV
算术运算指令
加法指令ADD
指令格式:
ADD{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn+<shifter_operand>
示例
ADD R0, R1, #0x80 //R0=R1+0x80
ADDEQ R0, R1, R3 //EQ, R0=R1+R3
ADDS R0, R1, R2
//R0=R1+R2,S,R0,根据R0影响NZCV
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C= CarryFrom(Rn + shifter_operand)
V= OverflowFrom(Rn + shifter_operand)
ADDS PC, R1, #0 //PC=R1,CPSR=SPSR
ADD R0, R1, R2 R0 = R1 + R2
ADD R0, R1, #256 R0 = R1 + 256
ADD R0, R2, R3, LSL #1 R0 = R2 + (R3 << 1)
NZCV:
N:运算结果为负值的标志位
N=1,负值
N=0,正值
Z:运算结果为0的标志位
Z=1,结果0
Z=0,结果为非0
C:运算结果产生进位的标志位
无符号
C=1,有进位
C=0,无进位
V:运算结果产生溢出的标志位
有符号
V=1,有溢出
V=0,无溢出
8bit
有符号:-128~127溢出
无符号:0~255进位
3AH+ 7CH =
无符号:58+ 124 = 182 无进位
有符号:58+ 124 = 182 有溢出
AAH+ 7CH =
无符号:170+ 124 = 294 有进位
有符号:-86+ 124 = 38 无溢出
带进位的加法指令:ADC
指令格式:
ADC{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd= Rn +<shifter_operand>+C位
示例
ADC R0, R1, #0x80 //R0=R1+0x80+C
ADCEQ R0, R1, R3 //EQ,R0=R1+R3+C
ADCS R0, R1, R2 //R0=R1+R2,S,R0
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C= CarryFrom(Rn + shifter_operand + C Flag)
V= OverflowFrom(Rn + shifter_operand + C Flag)
ADCS PC, R1, #0
加数(R1、R0),
被加数(R3、R2),
结果(R1、R0),
前者为高32位,后者为低32位
R1R0
+R3 R2
R1R0
ADDS R0, R0, R2 //R0=R0+R2结果影响NZCV
ADC R1,R1,R3 //R1=R1+R3+C
减法指令:SUB
指令格式:
SUB{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn-<shifter_operand>
示例
SUB R0, R1, #0x80 //R0=R1-0x80
SUBNE R0, R1, R3 //在NE,R0=R1-R3
SUBS R0, R1, R2 //R0=R1-R2,R0影响NZCV
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C= NOT BorrowFrom(Rn - shifter_operand)
有借位,C=0
无借位,C=1
V= OverflowFrom(Rn - shifter_operand)
SUBS PC, R14, #04 //PC=R14-4,S,PC,CPSR=SPSR
SUB R0, R1, R2
SUB R0, R1, #256
SUB R0, R2, R3, LSL #1
SUBS R1, R2, R3
SUBS PC, R14, #4
带借位的减法指令:SBC
指令格式:
SBC{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn-<shifter_operand>-Not C
示例
SBC R0, R1, #0x80 //R0=R1-0x80-Not C
SBCNE R0, R1, R3 //NE,R0=R1-R3-Not C
SBCS R0, R1, R2 //R0=R1-R2-Not C
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=NOTBorrowFrom(Rn - shifter_operand – NOT(C Flag))
V= OverflowFrom(Rn - shifter_operand – NOT(C Flag))
SBCS PC, R1, #0
被减数(R1、R0)
减数(R3、R2)
结果(R1、R0)
前者为高32位,后者为低32位
R1R0
R3R2
R1R0
SUBS R0, R0, R2 //R0=R0-R2,影响NZCV
SBC R1,R1,R3//R1=R1-R3-Not C
反向减法指令:RSB
指令格式:
RSB{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd= <shifter_operand>- Rn
示例
RSB R0, R1, #0x80
RSBNE R0, R1, R3
RSBS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C= NOT BorrowFrom(shifter_operand – Rn)
V= OverflowFrom(shifter_operand – Rn)
RSBS PC, R1, #0
RSB R3, R1, #0 //R3=-R1
RSBS R1, R2, R2, LSL #2 //R1=(R2<<2)-R2=R2×3
影响标志位
带借位的反向减法指令:RSC
指令格式:
RSC{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd=<shifter_operand>-Rn-NotC
示例
RSC R0, R1, #0x80
RSCNE R0, R1, R3
RSCS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=NOT BorrowFrom(shifter_operand – Rn – NOT(C Flag))
V= OverflowFrom(shifter_operand – Rn – NOT(C Flag))
RSCS PC, R1, #0
算术运算
ADD加法C=1进位,C=0,无进位
ADC带进位的加法
SUB减法C=0借位,C=1,无借位
SBC带借位减
RSB反向减
RSC带借位的反向减
位运算
与AND
指令格式:
AND{<cond>}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd= Rn & <shifter_operand>按位与
示例
AND R0, R1, #0x80
ANDNE R0, R1, R3
ANDS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=shifter_carry_out
ANDS PC, R1, #0xFFFFFFFF
AND R0,R1,R2
AND R0,R1,#0x80
ANDS R0, R1,R2,LSL#1
ANDEQ R3,R4,#0xFF
按位与操作实现什么功能:
&1用于判断某位是1还是0
&0用于清除某位
或操作ORR
指令格式:
ORR{<cond>}{S}<Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn|<shifter_operand>
示例
ORR R0, R1, #0x80
ORRNE R0, R1, R3
ORRS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=shifter_carry_out
ORRS PC, R1, #0x0
ORR R0, R1, #1
ORR R0, R1, R2
ORR R0, R1, R2, LSL #2
用或操作实现什么功能?
|1,将某位置1
|0,保持不变
异或EOR
指令格式:
EOR{<cond>}{S}<Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn^<shifter_operand>
示例
EOR R0, R1, #0x80
EOREQ R0, R1, R3
EORS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=shifter_carry_out
EORS PC, R1, #0x0
用异或操作实现什么功能?
相同,为0
不同,为1
1.判断两个数是否相等?
R1^ R2 == 0, R1==R2
2.把一个变量的某位与1做异或可以实现取反
0 1 1
1 1 0
3.加密
0x80^ 0xFF =1000 0000 ^ 1111 1111 =01111111 = 0x7F
0x7F^ 0xFF =0111 1111^ 1111 1111 =10000000 =0x80
EOR R0, R0, #FF
EOR R0, R0, R1
EORS R0, R0, #1
位清除BIC
指令格式:
BIC{cond}{S} <Rd>, <Rn>, <shifter_operand>
功能:Rd=Rn&(~<shifter_operand>)
示例
BIC R0, R1, #0x80
BICEQ R0, R1, R3
BICS R0, R1, R2
N= Rd[31]
Z= if Rd == 0 then 1 else 0
C=shifter_carry_out
BICS PC, R1, #0x0
BIC R0, R0, #0xFF
BIC R1,R2,R3
AND
ORR
EOR
BIC
比较测试指令
比较指令CMP
指令格式
CMP{cond} <Rn>, <shifter_operand>
功能:Rn-<shifter_operand>
1.没有目标寄存器
2.不用加S,Rn-<shifter_operand>影响NZCV
示例
CMP R0, #0x80
CMPEQ R0, R3
N=ALU_out[31]
Z= if ALU_out == 0 then 1 else 0
C=NOTBorrowFrom(Rn - shifter_operand)
V=OverflowFrom(Rn- shifter_operand)
cmp r1, #10 r1-10
moveq r0, r1 Z=1
bleq test Z=1
……
test:
……
负值比较指令:CMN
指令格式
CMN{cond} <Rn>, <shifter_operand>
功能:Rn+<shifter_operand>
示例
CMN R0, #0x80
CMNEQ R0, R3
N=ALU_out[31]
Z= if ALU_out == 0 then 1 else 0
C= CarryFrom(Rn + shifter_operand)
V= OverflowFrom(Rn + shifter_operand)
CMN R1,#5;R1+5==0 Z=1 EQ
BEQ SKIP
......
SKIP:
……
位测试指令:TST
指令格式:
TST{cond} Rn, shifter_operand
功能:Rn& shifter_operand
示例
TST R0, #0x80
TSTEQ R0, R3
N=ALU_out[31]
Z= if ALU_out == 0 then 1 else 0
C= shifter_carry_out
TST R0, #0x1
ADDEQ R1,R2,R3
TST R1,R4
相等测试指令:TEQ
指令格式:
TEQ{cond} <Rn>, <shifter_operand>
功能:Rn^ <shifter_operand>
示例
TEQ R0, #0x80
TEQNE R0, R3
N=ALU_out[31]
Z= if ALU_out == 0 then 1 else 0
C= shifter_carry_out
TEQ R0,R1 R0==R1 Z=1 EQ
R0!=R1Z=0 NE
MOVNE R0,R1
数据处理指令:
1.数据传送(MOVMVN)
2.算术运算(ADDADC SUB SBC RSB RSC)
进位:C=1有进位,C=0无进位
借位:C=1无借位,C=0有借位
3.位运算(ANDORR EOR BIC)
4.比较测试(CMP- CMN+ TST& TEQ^ )
一般格式:
操作码{条件码}S目标寄存器,第一源操作数,第二源操作数
<opcode>{cond}{S} <Rd>, <Rn>, <shifter_operand>
1.第一源操作只能是寄存器
2.第二源操作数:
8位图立即数(#rot,8bit立即数,ROR)
寄存器
寄存器移位(LSL,LSR,ASR,ROR,RRX)
3.S:
1.目标寄存器为PC,CPSR=SPSR,异常返回
2.目标寄存器不是PC,根据运算结果影响NZCV
4.数据传送指令没有第一源操作数
5.比较测试指令没有目标寄存器,不加S,结果影响NZCV
用汇编指令实现1-10累加和计算
mov
add
sub
cmp
b
求最大公约数
20 12
R0=20
R1=12
while(R0!=R1)
{
if(R0>= R1) cmp
{
R0= R0 - R1条件执行cs
}
else
{
R1= R1 – R0条件执行cc
}
}
mov
cmp
sub
b
- ARM指令集2
- ARM指令集2
- ARM 汇编指令学习:[2]ARM指令集
- ARM指令集详解2
- ARM汇编指令集2
- ARM指令集--移位指令
- ARM 指令集>>跳转指令
- ARM指令集 LDR指令
- ARM 指令集 比较指令
- arm指令集比较指令
- arm指令集分支指令
- ARM汇编指令集2 --常用的汇编指令
- ARM指令集
- ARM 指令集
- ARM指令集
- ARM 指令集
- ARM指令集
- ARM 指令集摘要
- 【VSCode】Windows下VSCode编译调试c/c++
- App优化之性能分析工具
- Linux进程优先级的调整方法
- PsSetLoadImageNotifyRoutine回调函数中使用NtProtectVirtualMemory卡死原因
- 图像梯度的描述
- ARM指令集2
- 用Vue实现一个全选指令
- Android一键发布内测平台插件
- svn 被锁定的集中解决方案
- yum和apt-get的区别
- 无人机光电系统图像处理模块AVT22
- Day3: Meeting friend in Beijing
- 安装AndroidStudio
- Java中Vector、List、Set集合、Iterator迭代器的使用