必须知道的ARM指令集讲述
常用的ARM指令集
我们知道CPU能直接识别的是机器码,也就是0和1组合的东东。不同的组合代表不同的含义,CPU就做不同的事情。按照道理来说,我们写的代码都应该是0和1组成的东西,但是如果真的是那样,那结果....。人类是聪明的,发明了汇编语言,汇编语言是用一些助记符,来代替机器码。当然,汇编语言是不能给CPU识别的,需要编译器将其编译成机器码。
汇编语言是和特定的CPU关联的,不同的CPU对应不同的汇编指令。好在,现在大多数嵌入式CPU都是使用ARM架构的,这样我们只需要学会ARM的汇编指令集,我们写的汇编程序就可以在这些使用ARM架构的CPU上运行。
ARM的汇编指令很多,很难将其全部记住,其实也没必要,我们只需要学会一些常用的ARM汇编指令即可。其他的用到再去查即可。下面我们就开始,必须知道的ARM指令学习。
一、ARM指令格式
ARM指令的基本格式如下:
其中号内是必须的,{}号内的项是可选的。
各项的说明如下:
opcode :指令助记符
cond :执行条件
S :是否影响CPSR寄存器的值
Rd :目标寄存器(一般用来存放指令执行最后的结果)
Rn :第1个操作数的寄存器
operand2 :第2个操作数
1. 其中,我们必须要研究一下operand2这个操作数,它有如下表现形式
(1)#immed_8r——常数表达式
该常数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到,这个数我们也成立即数。
例如:
MOV R0,#1
AND R1,R2,#0x0
例如:0可以拿0x12循环右移位10位得到,所以它是一个合法的立即数。
有人会问,是不是每次我都要去判断一个数是不是立即数,我就需要从0x00~0xff里面找出一个数,将它循环右移偶数个位看是否能的得到,那太麻烦了。有没有一些快速识别的方法呢?肯定是有的呀,当然也不能完全依赖哦,最好就是拿编译器验证,不是,编译器就会报错。
如何判断一个数是否是合法立即数?
首先将这个数转换为32bit 16进制形式,例如218=0xDA=0x000000DA
1.除零外,仅有一位数为合法立即数。
2.除零外,仅有二位数,并且相邻(包括首尾,如0x1000000A)的为合法立即数。
3.除零外,仅有三位数,并且相邻(包括中间有0相间,例如0包括首尾??邻,如:0,这三位数中,最高位取值仅能为1、2、3,最低位取值仅能为4、8、C,中间位0x0~0xF。这种组合的为合法立即数。
除了以上三种,其他基本是非法立即数。
举例:
0xFF是有效立即数。
0x104是有效立即数。
0xFF0、0xFF00、0xFF000、0xFF000000、0xF000000F都是有效立即数。
反例:
0x101是无效立即数。
0x102是无效立即数。
0xFF1、0xFF04、0xFF003、0xFFFFFFFF都是无效立即数。
还有一个要说的就是:只要该数,可以通过0x00-0xFF中某个数,循环右移偶数位而产生,就是合法的立即数,否则就是非法的立即数。
练习: 下面哪些立即数是数据处理指令中有效的数据?
a) 0x00AB0000 b) 0x0000FFFF c) 0xF000000F
d) 0 e) 0x00001f80 f) 0xFFFFFFFF(2)Rm——寄存器方式
在寄存器方式下,操作数即为寄存器的数值。
例如:
SUB R1,R1,R2
MOV PC,R0
(3)Rm,shift——寄存器移位方式
将寄存器的移位结果作为操作数,但Rm值保持不变,移位方法如下:
例如:
ADD R1,R1,R1,LSL #3 ;R1=R1+R1*8=9R1
SUB R1,R1,R2,LSR R3 ;R1=R1-(R2/2R3)
2.ARM指令集——条件码
使用条件码“cond”可以实现高效的逻辑操作,提高代码效率。
所有的ARM指令都可以条件执行,而Thumb指令只有B(跳转)指令具有条件执行 功能。如果指令不标明条件代码,将默认为无条件(AL)执行。
其中上图,红线括起来的必须记住,其他不知道的时候在回过头查即可。
例如:
二、ARM指令
1.ARM 数据处理指令
数据处理指令大致可分为3类:
数据传送指令,算术逻辑运算指令,比较指令
注意:数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,并影响状态标志。
(1)数据传送
MOV指令将立即数或寄存器传送到目标寄存器(Rd),可用于移位运算等操作。指令格式如下:
原创力文档

文档评论(0)