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

一个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 ff
the value is ff
the value is ff
the 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 ffffffff
the value is ffffffff
the value is ffffffff
the value is 0
请按任意键继续. . .

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值