ARM汇编之合法立即数的快速判断方法
了个比较快速的方法:(简而言之,就是利用立即数的生成方法,迅速逆推到合法的8位常熟)
1、把数据转换成二进制形式,从低位到高位写成4位1组的形式,最高位一组不够四位的,在最高位前面补0。
2、数1的个数,如果大于8个肯定不是立即数,如果小于等于8进行下面步骤。
3、如果数据中间有连续的大于等于24个0,循环左移4的倍数,使高位全为0。
4、找到最高位的1,去掉前面最大偶数个0。
5、找到最低位的1,去掉后面最大偶数个0。
6、数剩下的位数,如果小于等于8位,那么这个数就是立即数,反之就不是立即数。
针对可能现的情况,举5个典型例子:
(1)0x4FF (2)0x122 (3)0x234 (4)0xF000000F (5)0x8000007F
例1: 0x4FF
第一步:0100 1111 1111
第二步:其中1的个数是9个,大于8个,判定不是立即数
例2: 0x122
第一步: 0001 0010 0010
第二步: 其中1的个数4个,小于8,继续
第三步: 其中没有连续大于等于24个0,继续
第四部: xx01 0010 0010 (最高位前面有3个0,最大偶数2,去掉2个0)
第五步: xx10 0011 0010 (最低位后面只有1个0,最大偶数0)
第六部: 剩下10 0011 0010 共10位,大于8,判定0x122不是立即数
例3: 0x234
第一步: 0010 0011 0100
第二步: 其中1的个数4个,小于8,继续
第三步: 其中没有连续大于等于24个0,继续
第四部: xx10 0011 0100
第五步: xx10 0011 01xx
第六部: 剩下10 0011 01 共8位,等于8,判定0x234是立即数
例4: 0xF000000F
第一步: 1111 0000 0000 0000 0000 0000 0000 1111
第二步: 其中1的个数8个,没有大于8,继续
第三步: 其中有连续24个0,循环左移4位,使高位全为0
0000 0000 0000 0000 0000 0000 0000 1111 1111
第四部: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111
第五步: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111
第六部: 剩下1111 1111共8位,等于8,判定0xF000000F是立即数
例5: 0x8000007F
第一步: 1000 0000 0000 0000 0000 0000 0111 1111
第二步: 其中1的个数8个,没有大于8,继续
第三步: 其中有连续24个0,循环左移4位,使高位全为0
0000 0000 0000 0000 0000 0000 0111 1111 1000
第四部: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx
第五步: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx
第六部: 剩下0111 1111 10共10位,等于8,判定0x7000008F是立即数
问题还没有结束,我们在ARM汇编中如何规避立即数这个问题呢,其实可以使用ARM汇编LDR伪指令,例如直接把MOV指令变为, LDR R1,=0x12345678这样编译器就不会报错了。但这种方法也有弊端会增加开销和影响执行效率。同时ARM汇编中还有有效数的概念,比如 MOV R1,#0xFFFFFFFF 指令中 0xFFFFFFFF 不是立即数,但是是有效数,编译器最自动把原指令变换为 MVN R1,#0,也不会报错。有效数判定:原数是立即数或者原数反码是立即数。
希望对大家有帮助。
ARM汇编合法立即 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)