zoukankan      html  css  js  c++  java
  • 汇编角度看C语言的参数传递、返回值,局部变量以及数组的反汇编

     1、   8位参数传递

    void Function(char x,char y,char z)            
    {            
                
    }            

    2、16位参数传递

    void Function(short x,short y,short z)                
    {                
                    
                    
    }                
                    

    3、32位参数传递

    void Function(int x,int y,int z)            
    {            
                
                
    }            
                

      

      通过反汇编可以得到结论,无论是char ,short ,int传入的时候都是四个字节

    原因:
      1、本机尺寸:如果本机是32位的,那么对32位的数据支持最好,如果是64位的,那么对64位的支持最好
      2、编译器遵守了这个规则:char类型或者short类型的参数不但没有节省空间,反而浪费了多余的操作.
      结论:整数类型的参数,一律使用int类型

    4、思考题

    //函数定义:            
    void Plus(int x)            
    {            
        x = x + 1;        
    }            
    //入口函数            
    int main(int argc, char* argv[])            
    {            
        int x = 1;        
                
        Plus(x);        
                
        printf("%d
    ",x);        
                
        return 0;        
    }            

      思考题:  main方法中,int x为局部变量,[ebp-4]中,而在调用的plus中为[ebp+8]中,

                            最后会把x=x+1的值重新写到ebp+8中。而不会影响main方法堆栈中的ebp-4的值

    5、

        示例1.  
        void Function()        
        {

      00E51760 push ebp
      00E51761 mov ebp,esp
      00E51763 sub esp,0C0h    分配了 0xC 个空间
      00E51769 push ebx
      00E5176A push esi
      00E5176B push edi
      00E5176C lea edi,[ebp-0C0h]
      00E51772 mov ecx,30h
      00E51777 mov eax,0CCCCCCCCh
      00E5177C rep stos dword ptr es:[edi]
      00E5177E mov ecx,offset _9B1CD70C_main-2-2@cpp (0E5C008h)
      00E51783 call @__CheckForDebuggerJustMyCode@4 (0E5131Bh)

    
        }        
    示例2.
    void
    Function(int x,int y) {

      00671760 push ebp
      00671761 mov ebp,esp
      00671763 sub esp,0C0h
      00671769 push ebx
      0067176A push esi
      0067176B push edi
      0067176C lea edi,[ebp-0C0h]
      00671772 mov ecx,30h
      00671777 mov eax,0CCCCCCCCh
      0067177C rep stos dword ptr es:[edi]
      0067177E mov ecx,offset _9B1CD70C_main-2-2@cpp (067C008h)
      00671783 call @__CheckForDebuggerJustMyCode@4 (067131void fun3(int i, int j)

    {
        int x = 4;
        int y = 5;
    
    
    
        mov  ebp, esp  
        sub sp, 0D8h  
        多分配了 0x18个字节的空间
        这个值在vc6++中是0x8个字节
    } 

      总结:
      1、小于32位的局部变量,空间在分配时,按32位分配.
      2、使用时按实际的宽度使用.
      3、不要定义char/short类型的局部变量.
      4、参数与局部变量没有本质区别,都是局部变量,都在栈中分配.
      5、完全可以把参数当初局部变量使用

    6、

    void Function()                    
    {                    
        int v_0 = 1;                
        int v_1 = 2;                
        int v_2 = 3;                
        int v_3 = 4;                
        int v_4 = 5;                
        int v_5 = 6;                
        int v_6 = 7;                
        int v_7 = 8;                
        int v_8 = 9;                
        int v_9 = 10;                
    }   
    
    
    
    反汇编:
        push        ebx
        push        esi
        push        edi
        lea         edi,[ebp-68h]
        mov         ecx,1Ah
        mov         eax,0CCCCCCCCh
        rep stos    dword ptr [edi]
        nt v_0 = 1;
        mov         dword ptr [ebp-4],1
        nt v_1 = 2;
        mov         dword ptr [ebp-8],2
        nt v_2 = 3;
        mov         dword ptr [ebp-0Ch],3
        nt v_3 = 4;
        mov         dword ptr [ebp-10h],4
        nt v_4 = 5;
        mov         dword ptr [ebp-14h],5
        nt v_5 = 6;
        mov         dword ptr [ebp-18h],6
        nt v_6 = 7;
        mov         dword ptr [ebp-1Ch],7
        nt v_7 = 8;
        mov         dword ptr [ebp-20h],8
        nt v_8 = 9;
        mov         dword ptr [ebp-24h],9
        nt v_9 = 10;
        mov         dword ptr [ebp-28h],0Ah
        
        pop         edi
        pop         esi
        pop         ebx
        mov         esp,ebp
        pop         ebp
        ret
    
    函数二:
     void Function()                    
    {                    
        int arr[10] = {1,2,3,4,5,6,7,8,9,10};                
    } 
    反汇编:
    
        push        ebp
        mov         ebp,esp
        sub         esp,68h
        push        ebx
        push        esi
        push        edi
        lea         edi,[ebp-68h]
        mov         ecx,1Ah
        mov         eax,0CCCCCCCCh
        rep stos    dword ptr [edi]
       int arr[10] = {1,2,3,4,5,6,7,8,9,10};
        mov         dword ptr [ebp-28h],1
        mov         dword ptr [ebp-24h],2
        mov         dword ptr [ebp-20h],3
        mov         dword ptr [ebp-1Ch],4
        mov         dword ptr [ebp-18h],5
        mov         dword ptr [ebp-14h],6
        mov         dword ptr [ebp-10h],7
        mov         dword ptr [ebp-0Ch],8
        mov         dword ptr [ebp-8],9
        mov         dword ptr [ebp-4],0Ah
     
        pop         edi
        pop         esi
        pop         ebx
        mov         esp,ebp
        pop         ebp
        ret

     总结

        1、数组就是一组相同类型的变量,为了方便读写,采用另外一种表示形式。在堆栈图中的表现形式是一样的

        2、数组在声明的时候,必须用常量来指明长度,不能使用变量.

    7、

    示例:                    
                        
    void Function()                    
    {                    
        int arr[10] = {1,2,3,4,5,6,7,8,9,10};                
                        
        int x = 1;                
        int y = 2;                
        int r ;                
                        
        r = arr[1];                
        r = arr[x];
        r = arr[x+y];
        r = arr[x*2+y];
        r = arr[arr[1]+arr[2]];         
        r = arr[Add(1,2)];          
        
    }                    
                        

      数组的使用总结

        1、数组在使用时,可以通过变量来定位数据.

        2、数组定位时,可以超过数组的长度,编译不会有错,但读取的数据是错的.

  • 相关阅读:
    [转载][QT][SQL]sql学习记录7_sqlite 日期 & 时间
    [转载][QT][SQL]sql学习记录6_sqlite Autoincrement(自动递增)
    [转载][QT][SQL]sql学习记录5_sqlite视图(View)
    [转载][QT][SQL]sql学习记录4_sqlite约束
    [转载][QT][SQL]sql学习记录3_sqlite之update delete like
    [转载][QT][SQL]sql学习记录2_sqlite数据类型
    [转载][QT][SQL]sq]学习记录1_模糊搜索
    [svn]显示日志很慢 点击文件查看更改记录也贼慢
    [QT]给QApplication安装事件过滤器 app.installEventFilter
    [QT]数据库SQLITE使用错误记录
  • 原文地址:https://www.cnblogs.com/heyhx/p/14217975.html
Copyright © 2011-2022 走看看