基于ARM9的汇编指令:数据传送指令,算术运算指令,比较指令和跳转指令

32位汇编指令集大体分为四大类,四大类又细分为13小类

大类1:3种类型的存储器访问指令;
功能:用于控制存储器与寄存器之间的数据传送。
小类1:用于优化的灵活寻址
小类2:用于快速上下文切换
小类3:用于交换数据

大类2:3种类型的数据处理指令;
功能:使用片内累加器ALU,桶形移位器和乘法器,对31个寄存器完成高速数据处理操作;

大类3:4种类型的分支指令;
功能:用于控制程序执行流程,指令优先级,ARM代码和Thumb代码的切换

大类4:3种类型的协处理器指令;
功能:专用于控制外部协处理器。
说明:这3类指令以开放和统一的方式扩展了指令集的片外功能;

数据传送指令
MOV 数据传送指令
栗子:
MOV R1,R0 //将寄存器R0中的值传送到寄存器R1中
MOV PC,R14 //将寄存器R14的值传送到PC,常用语子程序的返回
MOV R1,R0,LSL #2 //将寄存器R0的值左移2位后传送到R1
MOV R0,#10 //将立即数10传送到R0中

MVN 数据取反传送指令
栗子:
MVN R0,#0 //将立即数0按位取反后传送到寄存器R0中,即R0=-1;
MVN R1,R2 //将R2取反,结果存到R1中

算数运算指令
ADD 加法指令
栗子:
ADD R0,R1,R2 //R0=R1+R2
ADD R0,R1,#10 //R0=R1+10
ADD R0,R1,R2,LSL #3 //R0=R1+(R2左移3位)

ADC 带进位加法指令
栗子:两个64位的加法操作,高低位分开放置
ADDS R1,R3,R5 //低32位
ADC R0,R2,R4 //高32位

SUB 减法指令
栗子:
SUB R0,R1,R2 //R0=R1-R2
SUB R0,R1,#6 //R0=R1-6
SUB R0,R2,R3,LSL #1 //R0=R2-(R3左移1位)

SBC 带借位减法指令
栗子:两个64位的加法操作,高低位分开放置
SUBS R0,R0,R2 //低32位
SBC R1,R1,R3 //高32位

RSB 逆向减法指令
栗子:
PSB R0,R1,R2 //R0=R2-R1
PSB R0,R1,#5 //R0=5-R1
PSB R0,R1,R2,LSL #2 //R0 = (R2左移两位)-R1

RSC 带借位的逆向减法指令
栗子:
RSC R0,R1,R2 //R0=R2-R1-!C

MUL 32位乘法指令
栗子:
MUL R0,R1,R2 //R0=R1R2
MULS R0,R1,R2 //R0=R1
R2,同时设置CPSR中的相关条件标志
(特变注意:ARMv4及以前的版本中,标志C和V是不可靠的,在ARMv5以及后来的版本中不影响C和V标志)

MLA 32位乘加指令
栗子:
MLA R0,R1,R2,R3 //R0=R1R2+R3
MLAS R0,R1,R2,R3 //R0=R1
R2+R3,并设置CPSR中的相关条件标志位

SMULL 64位有符号数乘法指令
栗子:
SMULL R0,R1,R2,R3 //R0=(R2R3)的底32位,R1=(R2R3)的高32位

SMLAL 64位有符号数乘加指令
栗子:
SMLAL R0,R1,R2,R3 //R0=(R2R3)的低32位+R0,R1=(R2R3)的高32位字节+R1

UMULL 64位无符号数乘法指令
栗子:
UMULL R0,R1,R2,R3 //R0=(R2R3)的低32位, R1=(R2R3)的高32字节

UMLAL 64位无符号数乘加指令
栗子:
UMLAL R0,R1,R2,R3 //R0=(R2R3)+R0,R1=(R2R3)+R1

比较指令
用法:把一个寄存器和一个32位的数值进行比较或测试,比较的结果会更新CPSR中的标志位
特点:不需要使用S后缀就可以改变标志位的值。
比较的过程:一个寄存器的值减去一个32的值,结果并不保存,而是根据结果对CPSR中条件标志位的影响;

比较指令有下面4条:
CMP:比较指令
CMN:反值比较指令
TST:位测试指令
TEQ:相等测试指令

CMP:CMP{条件} 寄存器Rn,prerand2
栗子:
CMP R1,#10 //将寄存器R1的值和10相减,并设置结果CPSR标志位
ADDGT R0,R0,#5 //如果R1>10,则执行该指令:将R0加5

CMN:CMN{条件} 寄存器Rn,operand2
栗子:
CMN R0,R1 //将R0的值与R1的值相加,根据结果设置CPSR的比标志位
CMN R0,#10 //将R0的值加10,并根据结果设置CPSR的标志位
(纳尼?这不叫加法指令并且设置条件标志位了吗?)

TST:TST{条件} 寄存器Rn,operand2
这个比较指令稍微特别一下:
举例说明过程:
TST R0,#4
//#4可以理解为二进制32位的0000 0000 0000 0100;将#4和32位的寄存器进行与运算,不保存结果,若结果为0,则条件标志位Z被置1,若结果为1,则Z被清0;通过这中方法多是用于获得寄存器的具体位的值;

TEQ:TEQ{条件} 寄存器Rn,operand2
栗子:
TEQ R0,R1 //若R0==R1,则使Z=0;否则为1;

跳转指令
实现程序跳转的两种方法:

  1. 直接向R15(PC)中写入目标地址
  2. 使用跳转指令

B:无条件跳转
BL:带返回的跳转指令
BX:带状态切换的跳转指令
BLX:带返回和状态切换的跳转指令;

B:B{条件}label
栗子:
B 0x1000 //跳转到绝对地址0x1000处执行
条件跳转:
BCC foward //当C=1时,程序跳转到标号forward处

BL:BL{条件} lable
与直接跳转指令不同,BL的跳转模式是:在跳转程序之前,将PC当前的内容加载到寄存器R14(LR)中,因此可以通过将R14的内容重新加载到PC中,再返回到跳转指令之后的那个指令处执行。该指令用于实现子程序的调用和,程序的返回可以通过被LR值传送到PC寄存器实现;
栗子:
……
BL func //跳转到子程序
ADD R1,R2,#2 //子程序调用完返回后执行的语句,返回地址
……
func //子程序
……
MOV R15,R14 //复制返回地址到PC,实现子程序的返回

BX:BX{条件}Rm
功能:跳转到Rm中多指定的目标地址,并实现状态转换;
Rm是一个表达目标寄存器地址的寄存器
功能:当Rm中的最低位Rm[0]=1时,强制程序从ARM状态转到Thumb状态;当Rm[0]=0时,程序从Thumb状态转到ARM状态;

BLX:{条件}label | Rm
功能:跳转到指令中所指定的目标地址,并实现状态的切换,同时将PC(R15)的值保存到LR(R14)中,其目的地址可以是一个符号地址label或者一个表达地址的寄存器Rm。如果目标地址处为Thumb指令,则程序从ARM状态跳转到Thumb状态。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX实现子程序的调用和处理器工作状态的切换。同时子程序返回时,R14(LR)的值赋予给R15(PC)。

特别注意:BLX指令是在ARMv5框架下支持的分支指令

你可能感兴趣的:(ARM9,arm9,汇编,指令集)