一个C语言中unsigned和signed的汇编不同的插曲

来源:互联网 发布:单片机按键 编辑:程序博客网 时间:2024/05/22 17:11

一个C语言中unsigned和signed的汇编不同的插曲

首先代码如下:

void main(){    unsigned int  a = 0xffffff;    unsigned int len = sizeof(int);    for (int i = 0; i < len; i++)    {        unsigned char temp = ((char *)(&a))[i];        printf("the value is %x\n", temp);    }}对应的汇编语言如下:11: void main()    12: {00DB4C80  push        ebp  00DB4C81  mov         ebp,esp  00DB4C83  sub         esp,0F0h  00DB4C89  push        ebx  00DB4C8A  push        esi  00DB4C8B  push        edi  00DB4C8C  lea         edi,[ebp-0F0h]  00DB4C92  mov         ecx,3Ch  00DB4C97  mov         eax,0CCCCCCCCh  00DB4C9C  rep stos    dword ptr es:[edi]      13:     unsigned int  a = 0xffffff;00DB4C9E  mov         dword ptr [a],0FFFFFFh      14:     unsigned int len = sizeof(int);00DB4CA5  mov         dword ptr [len],4      15:     16:     for (int i = 0; i < len; i++)00DB4CAC  mov         dword ptr [ebp-20h],0  00DB4CB3  jmp         main+3Eh (0DB4CBEh)  00DB4CB5  mov         eax,dword ptr [ebp-20h]  00DB4CB8  add         eax,1  00DB4CBB  mov         dword ptr [ebp-20h],eax  00DB4CBE  mov         eax,dword ptr [ebp-20h]  00DB4CC1  cmp         eax,dword ptr [len]  00DB4CC4  jae         main+64h (0DB4CE4h)      17:     {    18:         unsigned char temp = ((char *)(&a))[i];00DB4CC6  mov         eax,dword ptr [ebp-20h]  00DB4CC9  mov         cl,byte ptr a[eax]  00DB4CCD  mov         byte ptr [ebp-29h],cl      19:         printf("the value is %x\n", temp);00DB4CD0  movzx       eax,byte ptr [ebp-29h]     (注意这个地方,是movzx,程序在这里是零扩展)00DB4CD4  push        eax  00DB4CD5  push        offset string "the value is %x\n" (0DB6CD0h)  00DB4CDA  call        _printf (0DB1320h)  00DB4CDF  add         esp,8      20:     21:     }00DB4CE2  jmp         main+35h (0DB4CB5h)      22: }程序运行结果是the value is ffthe value is ffthe value is ffthe value is 0请按任意键继续. . .

另一种情况如下,这里使用的是数据都是带符号的,所以汇编的时候就会编译处movsx的移动命令。

void main(){     int  a = 0xffffff;     int len = sizeof(int);    for (int i = 0; i < len; i++)    {         char temp = ((char *)(&a))[i];        printf("the value is %x\n", temp);    }}汇编结果是:  11: void main()    12: {01204C80  push        ebp  01204C81  mov         ebp,esp  01204C83  sub         esp,0F0h  01204C89  push        ebx  01204C8A  push        esi  01204C8B  push        edi  01204C8C  lea         edi,[ebp-0F0h]  01204C92  mov         ecx,3Ch  01204C97  mov         eax,0CCCCCCCCh  01204C9C  rep stos    dword ptr es:[edi]      13:      int  a = 0xffffff;01204C9E  mov         dword ptr [a],0FFFFFFh      14:     unsigned int len = sizeof(int);01204CA5  mov         dword ptr [len],4      15:     16:     for (int i = 0; i < len; i++)01204CAC  mov         dword ptr [ebp-20h],0  01204CB3  jmp         main+3Eh (01204CBEh)  01204CB5  mov         eax,dword ptr [ebp-20h]  01204CB8  add         eax,1  01204CBB  mov         dword ptr [ebp-20h],eax  01204CBE  mov         eax,dword ptr [ebp-20h]  01204CC1  cmp         eax,dword ptr [len]  01204CC4  jae         main+64h (01204CE4h)      17:     {    18:          char temp = ((char *)(&a))[i];01204CC6  mov         eax,dword ptr [ebp-20h]  01204CC9  mov         cl,byte ptr a[eax]  01204CCD  mov         byte ptr [ebp-29h],cl      19:         printf("the value is %x\n", temp);01204CD0  movsx       eax,byte ptr [ebp-29h]    (注意这里是movsx,是带符号的扩展)01204CD4  push        eax  01204CD5  push        offset string "the value is %x\n" (01206CD0h)  01204CDA  call        _printf (01201320h)  01204CDF  add         esp,8      20:     21:     }01204CE2  jmp         main+35h (01204CB5h)      22: }01204CE4  xor         eax,eax  01204CE6  push        edx  01204CE7  mov         ecx,ebp  01204CE9  push        eax  01204CEA  lea         edx,ds:[1204D0Ch]      22: }程序运行结果是the value is ffffffffthe value is ffffffffthe value is ffffffffthe value is 0请按任意键继续. . .

通过这个函数,我们可以看出来对于unsinged和signed数据的使用一定要注意,考虑到汇编对于两者的不同编译方向。

原创粉丝点击