在ARM立即数寻址中,指令中的立即数是有一个8位的常熟和移动的4 位偶数位得到的,所以每一条指令都包含一个常数X和移位值Y,得到的立即数=X循环右移(2*Y)
给定一个立即数,判断其是否合法可以分三步:首先将给定的立即数写成32位二进制的形式;然后看能不能用一个8位的二进制数包括所有含1的部分,如不能则非法;最后看这个8位二进制数能不能循环右移偶数位得到给定的立即数,不能数则非法。
下面给出判断一个16进制的数是否为ARM的立即数的C语言代码;
#include <stdio.h> #define ture 1 #define false 0 unsigned int rightmove(int num,int bit) ;//把num数右移bit位 void prin2(unsigned int num) ; //十进制转打印二进制数 bool judge(unsigned int num) ; //判断是否是立即数 int main() { bool decide ; unsigned int num ; printf("本台电脑unsigned int类型是%d位\n",sizeof(unsigned int)*8) ; //打印电脑int类型是否是32位字节,输出4则是 printf("请输入16进制的判断数") ; while(1) { scanf("%p",&num) ; decide = judge(num) ; decide == ture ?printf("yes!\n") : printf("no!\n") ; } return 0 ; } /*a 总长度N(8 16 32) 循环左移n (a >> (N - n)) | (a >> n) 循环右移n (a << (N - n)) | (a >> n) */ unsigned int rightmove(unsigned int num,int bit) //把num数右移bit位 { num = (num << (32 - bit)) | (num >> bit) ; return num ; } bool judge(unsigned int num) //判断是否是立即数 { int i ; unsigned int num_bak ; i = 32 ; for(i = 0 ;i < 32 ;i++) { num_bak = rightmove(num,i) ; //printf("%10x ",num_bak) ; prin2(num_bak) ; if(num_bak <= 0x00ff ) { if(i % 2 == 0) { return true ; } } } return false ; } void prin2(unsigned int num) { int i = 0 ,j = 31; char bit[32] ; for(i = 0 ;i < 32 ;i++) { bit[j--] = (num >> i) & 0x01 ; } j = 0 ; while(j < 32) { printf("%d",bit[j++]) ; if(j % 4 ==0 ) { printf(" ") ; } } puts("") ; } //注意:输入的16进制的数必须是unsigned int 类型,如果不是,则会导致判断错误,因为有一个符号位会干扰移位值与0xFF的比较。代码中输出了每一次移位后的二进制数,请读者根据现实理解立即数的有效判断。