本机尺寸

Posted newen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了本机尺寸相关的知识,希望对你有一定的参考价值。

如果本机是32位的,那么对32位的支持是最好的

在很多的书上都能看到类似这样的代码

#include<stdio.h>
void Function(char x,char y)
{
    char c=x+y;
}
void main()
{
    char a=1;
    char b=2;
    Function(a,b);
}

我们通过反汇编会发现

1:    #include<stdio.h>
2:    void Function(char x,char y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:        char c=x+y;
00401038   movsx       eax,byte ptr [ebp+8]
0040103C   movsx       ecx,byte ptr [ebp+0Ch]
00401040   add         eax,ecx
00401042   mov         byte ptr [ebp-4],al
5:    }
00401045   pop         edi
00401046   pop         esi
00401047   pop         ebx
00401048   mov         esp,ebp
0040104A   pop         ebp
0040104B   ret
--- No source file  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0040104C   int         3
0040104D   int         3
0040104E   int         3
0040104F   int         3
--- C:\Windows\System32\a.cpp  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6:    void main()
7:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,48h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-48h]
0040105C   mov         ecx,12h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
8:        char a=1;
00401068   mov         byte ptr [ebp-4],1
9:        char b=2;
0040106C   mov         byte ptr [ebp-8],2
10:       Function(a,b);
00401070   mov         al,byte ptr [ebp-8]
00401073   pusheax
00401074   mov         cl,byte ptr [ebp-4]
00401077   pushecx
00401078   call        @ILT+0(Function) (00401005)
0040107D   add         esp,8
11:   }
00401080   pop         edi
00401081   pop         esi
00401082   pop         ebx
00401083   add         esp,48h
00401086   cmp         ebp,esp
00401088   call        __chkesp (004010a0)
0040108D   mov         esp,ebp
0040108F   pop         ebp
00401090   ret

蓝色部分是传递进去的参数

然后我们发现,尽管定义的是char类型,压栈的却是eax而并不是al。

在32位的系统中,系统默认最合适的数据类型,就是32个bit,即4字节。同理,64位的系统就是8字节。

也就是说,如果使用小于4个字节的局部变量来进行参数传递,vc编译器仍然会按照4个字节来进行传递,但是多余的部分并不会使用。

 

 

从上面我们能看到,当创建一个小于4字节局部变量时,编译器为我们分配的内存空间为0x44。

当我们创建两个局部变量时

1:    #include<stdio.h>
2:    void Function(char x,char y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,44h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-44h]
0040102C   mov         ecx,11h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:        char c=x+y;
00401038   movsx       eax,byte ptr [ebp+8]
0040103C   movsx       ecx,byte ptr [ebp+0Ch]
00401040   add         eax,ecx
00401042   mov         byte ptr [ebp-4],al
5:        char d;
6:    }
00401045   pop         edi
00401046   pop         esi
00401047   pop         ebx
00401048   mov         esp,ebp
0040104A   pop         ebp
0040104B   ret
--- No source file  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0040104C   int         3
0040104D   int         3
0040104E   int         3
0040104F   int         3
--- C:\Windows\System32\a.cpp  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,48h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-48h]
0040105C   mov         ecx,12h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:        char a=1;
00401068   mov         byte ptr [ebp-4],1
10:       char b=2;
0040106C   mov         byte ptr [ebp-8],2
11:       Function(a,b);
00401070   mov         al,byte ptr [ebp-8]
00401073   push        eax
00401074   mov         cl,byte ptr [ebp-4]
00401077   push        ecx
00401078   call        @ILT+0(Function) (00401005)
0040107D   add         esp,8
12:   }
00401080   pop         edi
00401081   pop         esi
00401082   pop         ebx
00401083   add         esp,48h
00401086   cmp         ebp,esp
00401088   call        __chkesp (004010a0)
0040108D   mov         esp,ebp
0040108F   pop         ebp
00401090   ret

缓冲区变为0x48了

再尝试创建一个大于4字节的数

1:    #include<stdio.h>
2:    void Function(char x,char y)
3:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,4Ch
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-4Ch]
0040102C   mov         ecx,13h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
4:        char c=x+y;
00401038   movsx       eax,byte ptr [ebp+8]
0040103C   movsx       ecx,byte ptr [ebp+0Ch]
00401040   add         eax,ecx
00401042   mov         byte ptr [ebp-4],al
5:        __int64 d;
6:    }
00401045   pop         edi
00401046   pop         esi
00401047   pop         ebx
00401048   mov         esp,ebp
0040104A   pop         ebp
0040104B   ret
--- No source file  ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0040104C   int         3
0040104D   int         3
0040104E   int         3
0040104F   int         3
--- C:\Windows\System32\a.cpp  -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7:    void main()
8:    {
00401050   push        ebp
00401051   mov         ebp,esp
00401053   sub         esp,48h
00401056   push        ebx
00401057   push        esi
00401058   push        edi
00401059   lea         edi,[ebp-48h]
0040105C   mov         ecx,12h
00401061   mov         eax,0CCCCCCCCh
00401066   rep stos    dword ptr [edi]
9:        char a=1;
00401068   mov         byte ptr [ebp-4],1
10:       char b=2;
0040106C   mov         byte ptr [ebp-8],2
11:       Function(a,b);
00401070   mov         al,byte ptr [ebp-8]
00401073   push        eax
00401074   mov         cl,byte ptr [ebp-4]
00401077   push        ecx
00401078   call        @ILT+0(Function) (00401005)
0040107D   add         esp,8
12:   }
00401080   pop         edi
00401081   pop         esi
00401082   pop         ebx
00401083   add         esp,48h
00401086   cmp         ebp,esp
00401088   call        __chkesp (004010a0)
0040108D   mov         esp,ebp
0040108F   pop         ebp
00401090   ret

这里就变成0x4c,因为__int64是8位的,所以就是0x48+4=0x4c了。

总结:

0x00.在32位系统上创建小于32位的局部变量是不合适的,在空间分配时仍然会按照32位来进行分配。但多余部分并不会使用。所以尽量避免使用小于32位的局部变量。

0x01.在vc6.0中调用函数时,每创建一个小于32位的局部变量,就会分配4个字节的空间。如果创建大于32位的局部变量,就会分配该局部变量实际的空间。

总的来说就是一句话,在32位的windows系统,使用vc6编程时尽量不要创建小于4个字节的局部变量,整数类型的参数,一律int类型。

以上是关于本机尺寸的主要内容,如果未能解决你的问题,请参考以下文章

如何更改以不同显示尺寸显示片段的方式?

Android 实用代码片段

Android 实用代码片段

如何在本机中处理不同的屏幕尺寸?

Android获取片段中的布局高度和宽度

如何在 Android 的滚动视图中放大/更改子图像视图尺寸以使图像全尺寸