在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的比較。代碼中輸出了每一次移位後的二進制數,請讀者根據現實理解立即數的有效判斷。