首页 > 程序开发 > 移动开发 > 其他 >

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

2017-04-24

基于ARM9的汇编指令:数据传送指令,算术运算指令,比较指令和跳转指令,32位汇编指令集大体分为四大类,四大类又细分为13小类。

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=R1*R2

MULS R0,R1,R2 //R0=R1*R2,同时设置CPSR中的相关条件标志

(特变注意:ARMv4及以前的版本中,标志C和V是不可靠的,在ARMv5以及后来的版本中不影响C和V标志)

MLA 32位乘加指令

栗子:

MLA R0,R1,R2,R3 //R0=R1*R2+R3

MLAS R0,R1,R2,R3 //R0=R1*R2+R3,并设置CPSR中的相关条件标志位

SMULL 64位有符号数乘法指令

栗子:

SMULL R0,R1,R2,R3 //R0=(R2*R3)的底32位,R1=(R2*R3)的高32位

SMLAL 64位有符号数乘加指令

栗子:

SMLAL R0,R1,R2,R3 //R0=(R2*R3)的低32位+R0,R1=(R2*R3)的高32位字节+R1

UMULL 64位无符号数乘法指令

栗子:

UMULL R0,R1,R2,R3 //R0=(R2*R3)的低32位, R1=(R2*R3)的高32字节

UMLAL 64位无符号数乘加指令

栗子:

UMLAL R0,R1,R2,R3 //R0=(R2*R3)+R0,R1=(R2*R3)+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框架下支持的分支指令

相关文章
最新文章
热点推荐