1. 程式人生 > 實用技巧 >彙編的角度分析C語言結構體

彙編的角度分析C語言結構體

1、定義:結構是 C 程式設計中另一種使用者自定義的可用的資料型別,它允許您儲存不同型別的資料項。

2、結構也可以看做是一種資料型別,與int float short char是平級關係

3、示例:

  加入開發一款遊戲,需要生命值,魔法值,座標等等的 AA 然後其中包含座標的結構體Point

  

struct Point
{
     float x;
     float y;
     float z;
   
}



struct AA           //定義一個 AA Game;   [0x41234566]   基址
{                   //一級偏移
      int
生命; //+4 int 魔法; //+ 8 Point 座標 //+10[座標] //二級偏移 //+4 float x //+8 float y
}

  

4、結構體的反彙編分析:

 原始碼:

#include "stdafx.h"


struct st
{
    int a;
    
char b; short c; }; //全域性變數 st x; void fun() { x.a=10; x.b=20; x.c=30; } void fun2() { int i=x.a; int j=x.b; int k=x.c; printf("%d %d %d",i,j,k); } int main(int argc, char* argv[]) { fun(); fun2(); return 0; }

反彙編:(fun 函式的反彙編)

00401030   push        ebp
00401031
mov ebp,esp 00401033 sub esp,40h //初始化堆疊依舊是0x40,沒有提升堆疊的空間,和空實現的函式宣告的空間一致 00401036 push ebx 00401037 push esi 00401038 push edi 00401039 lea edi,[ebp-40h] 0040103C mov ecx,10h 00401041 mov eax,0CCCCCCCCh 00401046 rep stos dword ptr [edi] 00401048 mov dword ptr [x (00427c48)],0Ah //int a 資料寬度為 dword 且直接複製到了記憶體中,而非在堆疊中。全域性變數 00401052 mov byte ptr [x+4 (00427c4c)],14h    //資料寬度為 byte                00401059 mov word ptr [x+6 (00427c4e)],offset fun+30h (00401060) //資料寬度為 word 00401062 pop edi 00401063 pop esi 00401064 pop ebx 00401065 mov esp,ebp 00401067 pop ebp 00401068 ret

fun2的反彙編程式碼分析:

00401080   push        ebp
00401081   mov         ebp,esp
00401083   sub         esp,4Ch  //提升了緩衝區的空間,三個變數多提升了 0xCh個位元組的空間。
00401086   push        ebx
00401087   push        esi
00401088   push        edi
00401089   lea         edi,[ebp-4Ch]
0040108C   mov         ecx,13h
00401091   mov         eax,0CCCCCCCCh
00401096   rep stos    dword ptr [edi]
00401098   mov         eax,[x (00427c48)]     //記憶體的值取到了暫存器
0040109D   mov         dword ptr [ebp-4],eax    //暫存器的值給了局部變數,複製到了堆疊中。也就是複製的過程,而記憶體的值並沒有消失
004010A0   movsx       ecx,byte ptr [x+4 (00427c4c)]   //寬度不到4個位元組的,帶符號擴充套件了
004010A7   mov         dword ptr [ebp-8],ecx     //擴充套件後,重新複製到堆疊中
004010AA   movsx       edx,word ptr [x+6 (00427c4e)]
004010B1   mov         dword ptr [ebp-0Ch],edx
004010B4   mov         eax,dword ptr [ebp-0Ch]
004010B7   push        eax
004010B8   mov         ecx,dword ptr [ebp-8]
004010BB   push        ecx
004010BC   mov         edx,dword ptr [ebp-4]
004010BF   push        edx
004010C0   push        offset string "%d %d %d" (0042201c)
004010C5   call        printf (00401150)
004010CA   add         esp,10h
004010CD   pop         edi
004010CE   pop         esi
004010CF   pop         ebx
004010D0   add         esp,4Ch
004010D3   cmp         ebp,esp
004010D5   call        __chkesp (004011d0)
004010DA   mov         esp,ebp
004010DC   pop         ebp
004010DD   ret

5、結構體中宣告結構體的反彙編

原始碼 :

struct Point    
{    
    double x;
    double y;
    double z;
};    


struct BB
{
    int i;
    int j;
    Point p;
    char name[20]; //20字元 10中文
};
BB b;
void fun(){

    b.i=3;
    b.j=6;
    b.p.x=13.4;
    b.p.y=17.6;
    b.p.z=21.3;

}



int main(int argc, char* argv[])
{
    fun();
    return 0;
}

反彙編分析:

00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,40h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-40h]
0040102C   mov         ecx,10h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
00401038   mov         dword ptr [b (0042bfe0)],3
00401042   mov         dword ptr [b+4 (0042bfe4)],6
0040104C   mov         dword ptr [b+8 (0042bfe8)],0CCCCCCCDh
00401056   mov         dword ptr [b+0Ch (0042bfec)],402ACCCCh
00401060   mov         dword ptr [b+10h (0042bff0)],9999999Ah
0040106A   mov         dword ptr [b+14h (0042bff4)],40319999h
00401074   mov         dword ptr [b+18h (0042bff8)],0CCCCCCCDh
0040107E   mov         dword ptr [b+1Ch (0042bffc)],40354CCCh
00401088   pop         edi
00401089   pop         esi
0040108A   pop         ebx
0040108B   mov         esp,ebp
0040108D   pop         ebp
0040108E   ret

6、結構體作為引數分析:

原始碼:

struct st    
{    
    char a;
    short b;
    int c;
    int d;
    int e;
    
};    
void Function(st s)    
{    
    
}    
int main(int argc, char* argv[])    
{    
    st s;
    s.a = 1;
    s.b = 2;
    s.c = 3;
    s.d = 4;
    s.e = 5;
    
    Function(s);
    
    
    return 0;
}    

反彙編分析:

00401040   push        ebp
00401041   mov         ebp,esp
00401043   sub         esp,50h        
00401046   push        ebx
00401047   push        esi
00401048   push        edi
00401049   lea         edi,[ebp-50h]
0040104C   mov         ecx,14h
00401051   mov         eax,0CCCCCCCCh
00401056   rep stos    dword ptr [edi]
00401058   mov         byte ptr [ebp-10h],1    //char型別一個位元組
0040105C   mov         word ptr [ebp-0Eh],offset main+20h (00401060)    //short型別兩個位元組
00401062   mov         dword ptr [ebp-0Ch],3    //int型別
00401069   mov         dword ptr [ebp-8],4   //int型別
00401070   mov         dword ptr [ebp-4],5   //int型別
00401077   sub         esp,10h      //堆疊提升0x10個位元組
0040107A   mov         eax,esp
0040107C   mov         ecx,dword ptr [ebp-10h]    //main函式第一個區域性變數與第二個區域性變數存入ecx中
0040107F   mov         dword ptr [eax],ecx    //把ecx放入到當前棧頂的位置
00401081   mov         edx,dword ptr [ebp-0Ch]
00401084   mov         dword ptr [eax+4],edx//把main函式的第三個區域性變數複製到當前棧頂+4的地方
00401087   mov         ecx,dword ptr [ebp-8]
0040108A   mov         dword ptr [eax+8],ecx//把main函式的第四個區域性變數複製到當前棧頂+8的位置
0040108D   mov         edx,dword ptr [ebp-4]
00401090   mov         dword ptr [eax+0Ch],edx//把main函式的第五個區域性變數複製到當前棧頂+C的位置
00401093   call        @ILT+10(fun) (0040100f)

7、結構體作為返回值分析:

  原始碼:

struct st    
{    
    char a;
    short b;
    int c;
    int d;
    int e;
    
};    
st Function()    
{    
    st s;
    s.a = 1;
    s.b = 2;
    s.c = 3;
    s.d = 4;
    s.e = 5;
    
    return s;
};    
int main(int argc, char* argv[])    
{    
    st s = Function();
    
    
    return 0;
}    

反彙編分析:

00410720   push        ebp
00410721   mov         ebp,esp
00410723   sub         esp,50h
00410726   push        ebx
00410727   push        esi
00410728   push        edi
00410729   lea         edi,[ebp-50h]
0041072C   mov         ecx,14h
00410731   mov         eax,0CCCCCCCCh
00410736   rep stos    dword ptr [edi]
00410738   mov         byte ptr [ebp-10h],1                             
0041073C   mov         word ptr [ebp-0Eh],offset Function+20h (00410740)    //區域性變數賦值
00410742   mov         dword ptr [ebp-0Ch],3                            
00410749   mov         dword ptr [ebp-8],4                              
00410750   mov         dword ptr [ebp-4],5                              
00410757   mov         eax,dword ptr [ebp+8]                            //main方法壓入的一個引數,也就是s的地址
0041075A   mov         ecx,dword ptr [ebp-10h]
0041075D   mov         dword ptr [eax],ecx         
0041075F   mov         edx,dword ptr [ebp-0Ch]
00410762   mov         dword ptr [eax+4],edx                            //依次把區域性變數的值,放入以main方法傳進來的地址為首的連續的地址中
00410765   mov         ecx,dword ptr [ebp-8]
00410768   mov         dword ptr [eax+8],ecx       
0041076B   mov         edx,dword ptr [ebp-4]
0041076E   mov         dword ptr [eax+0Ch],edx     
00410771   mov         eax,dword ptr [ebp+8]
00410774   pop         edi
00410775   pop         esi
00410776   pop         ebx
00410777   mov         esp,ebp
00410779   pop         ebp
0041077A   ret