ARM 汇编合法立即数判断
在ARM指令集中,一条汇编指令编码成32bits后,将不同的位数划分成不同的功能区间,比如条件码
和操作码
,还有比特位要留给指令本身和寄存器使用,通常情况下只有12-bits的长度可以用来表示立即数(immediate)。
12bits 可以表示的无符号数范围为:0~4095
,有符号数的范围为:-2048 ~ +2047
,如果不在这 12bits 的立即数上增加点创作性,而直接硬解码用来表示立即数是远远不够的。
所以在ARM中将这 12bits 分为 8bit 常数(0~255)和 4bit 循环右移位值(0~15)
-
8bit 常数范围(0~255)
-
位移的步进值是以2为单位(即实际位移
2 * rotate
位),可以表示循环有以(0~30)偶数位:0、2、4、6、8、10、12、14、16、18、20、22、24、26、28、30
循环右移
循环右移是一种位操作,指将一个数的二进制表示向右循环移动指定的位数。在循环右移中,移动的位数可以看作是一个循环,即当移动到数的最右侧时,移动的位重新出现在数的最左侧,从而形成一个闭环。
具体来说,循环右移的操作可以描述为将数的所有位向右移动,并将最右侧的位移到最左侧。移动过程中,被移出的位被循环地移动到数的最左侧,从而实现了循环的效果。
举个例子,假设有一个8位的二进制数 10101100
,如果对它进行循环右移3位,那么移位后的结果将是 10010101
,即原始数向右循环移动了3位,并将移出的位循环地移动到了最左侧。
在ARM指令集中,循环右移常用于对立即数的旋转操作,从而实现对立即数范围的扩展或者改变。通过循环右移,可以将立即数的高位移动到低位,从而实现对立即数值的调整或者变换。
判断合法立即数
立即数范围在 0x00 ~ 0xFF 肯定是合法立即数。
对于大于 0x00 ~ 0xFF 的立即数:
这个立即数的二进制序列的 最高位1至最低位1之间的二进制数序列(此二进制序列不超过8位,不足8位在高位(左边)补0) 右移 rotate(0~15) * 2
位后,和立即数本身的二进制数序列相等,则表示这个立即数数为合法立即数。
-
rotate(0~15) * 2
即0、2、4、6、8、10、12、14、16、18、20、22、24、26、28、30
- 最高位1至最低位1之间的二进制数序列,例如:
0000 0000 0000 0000 0000 0010 0011 0100
- 最高位1至最低位1之间:
1000 1101
先说结论
两个必要条件
-
最高位1至最低位1之间的二进制数序列的位数不超过8位,不足8位在高位补0(左边)
- 例如:
0000 0000 0000 0000 0000 0011 1111 0100
>1111 1101
- 例如:
0000 0000 0000 0000 0000 0001 0011 0010
>1001 1001
- 例如:
-
立即数的二进制序列的右边为偶数个连续的 0
- 例如:
0000 0000 0000 0000 0000 0011 1111 0100
,右边有2个连续的0,即偶数个0 - 例如:
0000 0000 0000 0000 0000 0001 0011 0010
,右边有1个连续的0,即奇数个0
- 例如:
FAQ
为什么最高位1至最低位1之间的二进制数序列的位数不能超过8位?
- 因为在ARM中将这 12bits 分为 8bit 常数(0~255)和 4bit 循环右移位值(0~15),只有8bit常数位,只能存下8位。
为什么立即数的二进制序列的右边必须为偶数个连续的 0
- 因为在ARM中将这 12bits 分为 8bit 常数(0~255)和 4bit 循环右移位值(0~15),循环右移位值步进是2,如果是奇数个连续的0,在提取其中的最高位1至最低位1之间的二进制数序列后,移动偶数次无法得到右边奇数个连续0的二进制序列,和立即数的二进制序列不相同。
验证
0x234
= 0000 0000 0000 0000 0000 0010 0011 0100
- 最高位1至最低位1之间的二进制数序列:
1000 1101
-
1000 1101
右移 30 位,可以得到0000 0000 0000 0000 0000 0010 0011 0100
- 和
0x234
本身的二进制相等,因此是合法立即数
0x3f4
= 0000 0000 0000 0000 0000 0011 1111 0100
- 最高位1至最低位1之间的二进制数序列:
1111 1101
-
1111 1101
右移 22 位,得到0000 0000 0000 0000 0000 0011 1111 0100
- 和
0x3f4
本身的二进制相等,因此是合法立即数
0x132
= 0000 0000 0000 0000 0000 0001 0011 0010
- 最高位1至最低位1之间的二进制数序列:
1001 1001
-
1000 1101
右移 30 位,得到0000 0000 0000 1001 1001
-
1000 1101
右移 28 位,得到0000 0000 0010 0110 0100
- 和
0x132
接近的两次偶数位右移都和0x132
本身的二进制不相等,因此不是合法立即数
0x7f8
= 0000 0000 0000 0000 0000 0111 1111 1000
文章来源:https://www.toymoban.com/news/detail-827628.html
- 最高位1至最低位1之间的二进制数序列:
1111 1111
-
1111 1111
右移 22 位,得到0000 0000 0000 0000 0000 0011 1111 1100
-
1111 1111
右移 20 位,得到0000 0000 0000 0000 0000 1111 1111 0000
- 和
0x7f8
接近的两次偶数位右移都和0x7f8
本身的二进制不相等,因此不是合法立即数
0xfab4
= 0000 0000 0000 0000 1111 1010 1011 0100
文章来源地址https://www.toymoban.com/news/detail-827628.html
- 最高位1至最低位1之间的二进制数序列:
0011 1110 1010 1101
-
0011 1110 1010 1101
右移 14 位,得到0000 0000 0000 0000 1111 1010 1011 0100
- 虽然和
0xfab4
本身的二进制相等,但是二进制序列超过了8位,因此不是合法立即数
到了这里,关于ARM 汇编合法立即数判断的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!