MOV指令分析
ARM指令的编码都是一个32位数,总共有15类,如图1所示:
图1 ARM指令集
这里主要分析第一类指令编码(Data/Processing/PSR Transfer),第一类指令编码包含了数据处理方面的指令,在这里我们以MOV指令作为分析对象,其他的数据处理方面的指令和MOV指令相似。
MOV 指令的语法格式
mov指令语法如下所示:
Rd为目的操作数,Op2为源操作数。Op2可以是立即数,也可以是寄存器(有移位操作的或没有移位操作的),如果是立即数,那么立即数的范围是多少呢?如果是寄存器,那么寄存器如何移位呢?下面来揭开MOV指令的面纱。
MOV指令的编码格式
图2给出了MOV指令的编码格式:
图2 MOV指令的编码格式
[31:28] 条件码
[25] 指明第二操作数(Operand2)是立即数还是寄存器;
[24:21] 操作码,MOV指令的操作码为1101;
[19:16] 第一操作数,第一操作数只能是寄存器,MOV指令中没用到,默认为0000;
[15:12] 目的寄存器;
[11:0] 第二操作数,也就源操作数,这是我们分析的重点;
源操作数(Operand2)的分析
我们前面讲了源操作数有两种情况:立即数或寄存器。
源操作数为立即数
我们先来看看立即数的情况,其格式如图3所示:
图3 Operand2(立即数)的格式
[11:8] 循环右移,占有4bit;这个4bit的无符号数乘以2就是循环右移的次数,也就是只能移偶数次,为什么要乘以2,这可能是为了尽量扩大立即数的范围。
[7:0] 8bit的无符号整数;
从这里我们可以看出,如果MOV的第二操作数为立即数,那么立即数的取值就只能由0到255中得某个数经过循环右移偶数次(包含0次)得到,其范围有两种情况:
ⅰ.0与255(包含0和255)之间的某个数,例如:
0x20 在0到255范围内。
ⅱ.如果立即数大于255,那么它必须能由0与255(包含0和255)之间的某个数经过循环右移偶数次得到,例如:
虽然0x200不在0到255的范围内,但是它可以由0x80循环右移30次得到,为什么这么移?结论是从其指令码中得到的,这条指令的指令码为e3a01f80。
下面这条指令就是错误的:
因为0x201无法由0到255中的任何数经过循环右移偶数次得到。
那么是不是就没有办法将0x201这样的数移入寄存器呢?不是。我们可以用下面伪指令将任何立即数“MOV”进寄存器:
源操作数为寄存器
如果源操作数是寄存器,那么其格式如图4所示:
图4 Operand2(寄存器)的格式
[3:0] 源操作数寄存器Rm;
[11:4] 应用于Rm的移位操作;
那么[11:4]的格式又是怎样的呢?这又得分两种情况,
第一种情况:移位数是立即数,例如:
Im为一个立即数,这条指令的意思是将r1中的值逻辑左移Im位放入r2中,这条指令的Operand2中的Rm为r1,而Shift对应的格式为图5的左半部分,从图中我们可以看出,移位数占5 bit,所以Im不能超过31,否则编译出错。
第二种情况:移位数在寄存器中,例如:
这条指令的意思是将r1中的值逻辑左移r3位放入r2中,这条指令的Operand2中的Rm为r1,而Shift对应的格式为图5的右半部分,移位数放在寄存器r3中。
图5 Shift格式
对ARM的MOV指令就分析到这里,对学习MOV指令的来龙去脉算是做个总结。本文中部分图来自S3C2440用户 手册。