ARM中判断立即数是否有效

时间:2020-12-15 05:18:47

        在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的比较。代码中输出了每一次移位后的二进制数,请读者根据现实理解立即数的有效判断。