合法的立即数

0x104 为什么是合法的
0x101 0x102 为什么不是
能一步一步清楚点么 我这太糊涂了
谢谢高手门

第1个回答  推荐于2018-11-29
1.如十六进制数在0x00到0xFF之间,则它一定是合法的

1.若十六进制数>0XFF则将十六进制的数转化成十进制

2.如果这个十进制数能够被4整除则这个十六进制的立即数和合法的,否则是非法的

3例如:0x101=257/4=64.25 非法

0x104=260/4=65 合法本回答被提问者和网友采纳
第2个回答  2018-06-19

立即数的定义:

每个立即数由一个8位的常数循环右移偶数位得到,其中循环右移的位数由一个4位二进制的两倍表示。如果立即数记为<immediate>, 8位常数记为immed_8, 4位的循环右移值记作rotate_imm, 则有:    <immediate>=immed_8循环右移(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数值选择最小的编码方式。

下面给出两条判断依据,判断一个立即数是否合法:

1:首先把这个数用二进制表示出来,然后看这个数中“1”的最大间隔是多少。要看两次,一次是顺序看,一次是循环看,循环看就是把16位或32位寄存器的首尾连起来,越过首尾来看,两次中如果最大间隔都大于8(包含首尾的两个1),那这个数肯定是非法的。如果有一次小于或等于8则有可能是合法的,可以进行下一步的判断。

2:此时又分为两种可能:

a:如果顺序看时“1”的最大间隔小于或等于8,此时可以看看,这个数的最高位1的前面或者最低位1的后面是否有偶数个0,只要有一种情况下有,这个数是合法的的立即数。

b:如果循环看时1的最大间隔小于或等于8,此时可以看看,循环看时,两端得到的间隔个数是否有一个为偶数,如果有一个为偶数,这个数就是合法的。

举例:

以下都是合法的

0xff=0000 0000 0000 0000 0000 0000 1111 1111B,首尾的两个1不大于8,符合2(a),是立即数

0x104=0000 0000 0000 0000 0000 0001 0000 0100B,首尾的两个1不大于8,符合2(a),是立即数

0xff0=0000 0000 0000 0000 0000 1111 1111 0000B,首尾的两个1不大于8,符合2(a),是立即数

来源:网页链接

相似回答