arm指令中存在两个操作数,而第二个操作数(opcode2)的其中一种形式可以用一个常数(#immed_8)表示。
#immed_8是一个常数表达式,该常数必须对应8位位图,即常数是由一个八位的常数向右循环移位偶数位而得到的。
常数对应8位位图是指一个大于8位的常数必须经过经过2*n次循环右移而得到的数:
eg:一个合法常数:0xf0000001(即0b1111,0000,0000,0000,0000,0000,0000,0001) 是由一个8位的数——0b0001,1111 经过2*2次循环右移而得到的。
则0xa0000001(0b1010,0000,0000,0000,0000,0000,0000,0001)是一个非法常数,虽然它可以由0b0000,1101右移3次而得到,但是我们的要求是常数是经过右移偶次位而得到的,显然该常数不合法。
为什么常数要对应8位位图?
由于一个ARM指令的opcode2放在该指令的低12位,其中低8位是用来存放数据,而高4位是用来存放移位次数。如下图:
则如果要完全运用到一个32位的寄存器(最大可存一个值为2^32 的数),则要把一个8位的数做移位处理。
而至于为什么是移位偶次位,是因为rot的最大值为2^4,则最多只能移位16次,而32位的寄存器要求最大移位次数为32次,因此只能把rot*2去满足要求。
PS:以上纯属个人理解,如有错之处,欢迎指正