立即数的定义:
每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数由一个4位二进制的两倍表示。如果立即数记为<immediate>, 8位常数记为immed_8, 4位的循环右移值记作rotate_imm, 则有: <immediate> = immed_8 ROR(2 * rotate_imm)
所以并不是每一个32位的常数都是合法的立即数,只有能够通过上述构造方法得到的才是合法的立即数,下面的常数是合法的立即数:
0xff, 0x104, 0xff0, 0xff00
而下面的常数不是合法的立即数:
0x101, 0x102, 0xff1
然而按照上面的构造方法,一个合法的立即数可能有多种编码方式,如 0x3f0 是一个合法的立即数,它可以采用下面的两种编码方式:
immed_8 = 0x3f,rotate_imm = 0xe
或者
immed_8 = 0xfc,rotate_imm = 0xf
但是,由于这种立即数的构造方法包含了循环右移操作,这将会影响 CPSR 的 C 位,因此,同一个合法的立即数采用了不同的编码方式,将会使某些指令的执行产生不同的结果,显然这是不允许的,ARM 汇编编译器按照下面的规则来产生立即数的编码:
1. 当立即数数值在 0 和 0xff 范围时,令 immed_8 = <immediate>,rotate_imm = 0
2. 其他情况下,汇编编译器选择使 rotate_imm 数值选择最小的编码方式。
参考自:blog.csdn.net/syp35/article/details/44903663,感谢博主。