arm指令集合分类
数据处理指令(Data Processing Instructions)
- 加法指令(ADD-Add):用于将两个操作数相加,并将结果存储在目标寄存器中。
ADD Rd,Rn,Operand2
- 减法指令(SUB-Subtract):用于从第一个操作数中减去第二个操作数,并将结果存储在目标寄存器中。
SUB Rd,Rn,Operand2
- 逻辑与指令(AND-Logical AND):对两个操作数进行逻辑与操作,并将结果存储在目标寄存器中。
AND Rd,Rn,Operand2
- 逻辑或指令(ORR-Logical OR):对两个操作数进行逻辑或操作,并将结果存储在目标寄存器中。
ORR Rd,Rn,Operand2
- 异或指令(EOR-Exclusive OR):对两个操作数进行异或操作,并将结果存储在目标寄存器中
EOR Rd,Rn,Operand2
- 移位和旋转指:左移 右移 算术右移 循环左移
LSL Rd, Rn, Operand2
LSR Rd, Rn, Operand2
ASR Rd, Rn, Operand2
ROR Rd, Rn, Operand2
- 比较指令(CMP-Compare):执行减法,但不保存结果,仅更新条件码寄存器。
CMP Rn,Operand2
- 测试指令(TST-Test):
执行逻辑与操作,但不保存结果,仅更新条件码寄存器。
TST Rn,Operand2
- 移动指令(MOV-Move):将源操作数的值直接移动到目标寄存器中。
MOV Rd,Operand2
数据传输指令
- 加载指令(LDR-Load Register):从存储器中加载数据到寄存器。
LDR Rd,[Rn,Operand2]
Rd是目标寄存器,Rn是基址寄存器,Operand2是可选的偏移量。
- 加载字节指令(LDRB-Load Register Byte):与LDR类似,但是加载一个字节。
LDRB Rd,[Rn,Operand2]
- 加载半字(半字)指令(LDRH-Load Register Hakfword):从存储器中加载半字(16位)到寄存器。
LDRH Rd,[Rn,Operand2]
- 加载多字(LDM-Load Multiple):一次性从存储器中加载多个字到一组寄存器。
LDM Rd!,{Rlist}//Rd是基址寄存器,Rlist是要加载的寄存器列表。
- 存储指令(STR-Store Register):将寄存器中的数据存储到存储器中。
STR Rd,[Rn,Operand2]
- 存储半字(半字)指令(STRH-Store Register Halfword):将寄存器中的半字(16位)存储到 存储器中。
STRH Rd,[Rn,Operand2]
- 存储多字(STM-Store Multiple):一次性将多个寄存器中的数据存储到存储器中。
STM Rd!,{Rlist}//Rd是基址寄存器,Rlist是要存储的寄存器列表
分支和跳转指令
- 条件分支指令(B系列-Conditional Branch):这些指令根据条件码(Condition Code)来确定是否执行跳转。条件码通常与上一条指令的执行结果相关联。
B{cond} label
{cond}是条件码,可以是EQ(等于)、NE(不等于)、GT(大于)、LT(小于)等。Label的目标标签,程序将在满足条件时跳转到该标签。
- 无条件分支指令(B-Unconditional Branch):无条件分支指令会无条件地改变程序计数器的值,实现跳转。
B label//label时目标标签,程序将无条件跳转到该标签。
- 子程序调用和返回指令(BL-Branch with Link,BX-Branch and Exchange)
BL用于调用子程序,并将返回地址存储在链接寄存器(LR)中。
BL label
- BX 用于无条件跳转到目标寄存器所指示的地址,通常用于返回子程序。
BX Rn
- 子程序返回指令(BLX-Branch with Link and Exchange):
BLX同时实现了调用子程序和返回子程序的功能,根据目标地址的位O来决定是跳转到Thumb模式还是ARM模式。
BLX label
- 异常处理指令(SWI-Software Interrupt)
SWI用于触发软中断,通常用于实现系统调用。
SWI #imm //#imm是一个立即数,用于指定软中断号。
- 异常返回指令(BKPT-Breakpoint):用于触发断点异常,通常用于调试
BKPT #imm
程序状态(PSR)和状态转移指令
程序状态寄存器(Program Status Register 简称PSR)是ARM体系结构中的一个寄存器,用于存储当前程序的状态信息,包括条件码(condition flags)、中断使能等。状态转移指令用于改变程序的执行状态,例如触发异常处理、改变中断状态等。
程序状态寄存器(PSR)
ARM架构中的程序状态寄存器(PSR)通常包含以下几个字段
-
条件码(Condition Flags)
用于存储上一条指令的执行结果,例如是否为零,是否溢出等。常见的条件码有零等于(Z)、负数(N)、溢出(V)、进位(C)等。 -
模式字段(Mode Bits)
表示当前处理器所处的模式,如用户模式、系统模式、中断模式等。不同模式下,处理器的权限和寄存器的可见性有所不同。 -
中断禁用位(Interrupt Disable Bit)
用于控制中断是否被禁用。如果该位为1,表示中断被禁用,如果为0,则中断被允许。、 -
执行状态(Execution State):
在ARMv7-A架构中,该位用于指示处理器的执行状态,例如ARM状态或Thumb状态。
协处理器指令
如:浮点运算、图形处理、向量运算等。ARM体系结构中的协处理器指令提供了一种标准的接口,允许主处理器与协处理器之间进行数据传递和协同操作。
协处理器数据操作指令(CDP-Co-processor Data Processing):
用于向协处理器发送数据和控制信息,让协处理器执行某种数据处理操作
CDP{cond} coproc,op1,CRd,CRn,CRm,op2
{cond}是条件码 coproc是协处理器编号 op1 CRd CRn CRm op2是操作数和寄存器字段。
协处理器数据传输指令(LDC/STC-Load/Store to Coprocessor)
用于从存储器中加载数据到协处理器寄存器,或将协处理器寄存器的数据存储到中。
LDC/STC{cond} coproc,CRd,[Rn,#offset]
{cond}是条件码 coproc是协处理器编号,CRd是目标寄存器 Rn是基地址寄存器 #offset是可选的偏移量。
协处理器寄存器传送指令(MCR/MRC-Move to/Move from Coprocessor)
用于在协处理器寄存器和ARM寄存器之间传递数据。
MCR/MRC{cond} coproc,op1,Rd,CRn,CRm,op2
乘法指令
- MUL指令(Multiply)
该指令用于执行两个寄存器中的数值相乘,并将结果存储在指定的目标寄存器中。
MUL Rd,Rm,Rs
Rd是目标寄存器,存放乘法结果;Rm和Rs是源寄存器,包含要相乘的两个数
MUL R0,R1,R2;将R1和R2中的值相乘,结果存储在R0中
- MLA指令(Multiply with Accumulate)
该指令执行两个寄存器中的数值相乘,然后将结果与第三个寄存器的值相加,最终将结果存储在指定的目标寄存器中。
MLA Rd,Rm,Rs,Rn
Rd是目标寄存器,存放相乘加相加的结果;Rm和Rs是源寄存器,包含要相乘的两个数;Rn是源寄存器,包含要相加的值。
MLA R3,R4,R5,R6;//将R4和R5中的值相乘,然后加上R6中的值,结果存储在R3中
单数据流(SIMD)指令
单数据流(Single Instruction Multiple Data,SIMD)指令是一种并行计算的指令,允许同时对多个数据进行相同的操作。在ARM体系结构中,SIMD指令集被称为NEON技术。NEON提供了一组用于向量操作的指令,可以在同一时间内处理多个数据元素。
向量寄存器(Q寄存器)
NEON引入了一组向量寄存器,每个向量寄存器可以容纳多个数据元素。通常,NEON指令分为128位(16字节)和64位(8字节)的向量,可以容纳多个32位或16位数据元素。
VN.168;//表示一个128位的向量寄存器,可以容纳16个字节数据
向量加载/存储指令(VLD/VST-Vector Load/Store)
用于从内存加载向量数据,或将向量数据存储到内存中。
VLD1.32 {D0-D3},[R0];//从内存地址R0加载四个32位元素到寄存器D0-D3中
VST1.32 {D4-D7},[R1];//将寄存器D4-D7中的四个32位元素存储到内存地址R1中
向量运算指令
NEON提供了一系列的算术和逻辑运算指令,可同时对向量寄存器中的多个数据元素执行相同的操作。
VADD.F32 Q1,Q2,Q3;//两个32位浮点数向量相加,结果存储在Q1中
VMLA.F32 Q4,Q5,Q6;//两个32位浮点数量相乘并累加到另一个向量,结果存储在Q4中
向量元素选择和操作指令
允许对向量寄存器中的单个元素进行选择、交换和其他操作。
VMOV.F32 S7,S8[1];//将Q8中的第二个32位浮点点复制到S7寄存器
VSWP.32 Q9,Q10;//交换两个32位整数向量的元素
归纳指令(Vector Reduction)
用于对向量寄存器中的元素进行归约操作,例如求和、最小值、最大值等。
VADDV.F32 S11,Q12;//对Q12中的32位浮点数元素进行求和,结果存储在S11中
浮点指令
浮点数加法、减法、乘法、除法等浮点指令集可以通过硬件浮点单元来实现,提高对浮点运算的 效率
- 浮点寄存器
ARM体系结构中包含一组浮点寄存器,通常以S和D开头表示单精度浮点数和双精度浮点数
S0,S1,...,S31;//单精度浮点寄存器,每个寄存器可以容纳一个32位浮点数
D0,D1,...,D15;//双精度浮点寄存器,每个寄存器可以容纳一个63位浮点数
- 浮点加载/存储指令
用于将浮点数加载到浮点寄存器中,或将浮点寄存器中的值存储到内存中。
VMOV S0,#2.5;//将立即数2.5加载到单精度浮点寄存器S0中
VMOV D1,#3.14;//将立即数3.14加载到双精度浮点寄存器D1中
VSTR S0,[R1];//将单精度浮点寄存器S0中的值存储到内存地址R1中
- 浮点加法指令(VADD-Vector Add):
VADD.F32 S2,S3,S4;//将S3和S4中的单精度浮点数相加,结果存储在S2中
- 浮点乘法指令(VMUL-Vector Multiply)
VMUL.F64 D5,D6,D7;//将D6和D7中的双精度浮点数相乘,结果存储在D5中
- 浮点除法指令(VDIV-Vector Divide)
VDIV.F32 S8,S9,S10;//将S9除以S10,结果存储在S8中
- 浮点比较指令(VCMP-Vector Compare)
VCMP.F64 D11,D12;//比较D11和D12中的双精度浮点数
ARM指令寻址方式
ARM指令集支持多种寻址方式,其中包括直接寻址、寄存器间接寻址、立即数寻址、寄存器相对寻址等。
- 直接寻址(Immediate Addressing)
直接将一个常数或立即数作为操作数
MOV R0,#10;//将值10直接存放到寄存器R0中
- 寄存器间接寻址(Register Indirect Addressing)
LDR R1,[R0];//从R0指向的地址加载数据到R1中
- 寄存器相对寻址(Register-relative Addressing)
LDR R2,[R1,#4];//从(R1+4)的地址加载数据到R2中
- 基地址加偏移寻址(Base Register Addressing with Offset)
LDR R3,[R4,#-8];//从(R4-8)的地址加载数据到R3中
- 相对寻址(PC-relative Addressing)
LDR R5,[PC,#12];//从(PC+12)的地址加载数据到R5中
- 多寄存器加载/存储(LDM/STM-Load/StoreMultiple)
一次性加载或存储一组寄存器的值,通常用于函数调用中
LDMIA R6,{R7,R8,R9};//从地址R6开始加载连续的3个寄存器的值
Thumb指令及应用
Thumb指令集是ARM体系结构中的一种指令集,皆在提高代码密度,降低存储器需求,同时保持对性能的合理权衡。Thumb指令集的指令长度为16位,相较于ARM指令集的32位,能够显著减小程序的体积。Thumb指令被广泛应用于嵌入式系统、移动设备和其他资源受限的环境中
本文作者:不会笑的孩子
本文链接:https://www.cnblogs.com/doubleconquer/p/17967854
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界