一个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数据的使用一定要注意,考虑到汇编对于两者的不同编译方向。