分析函数调用的汇编指令

原文链接:http://www.cnblogs.com/zhy2002/archive/2008/12/10/1351796.html

同样一段c++代码生成的汇编指令可能会不一样。有多种原因,例如编译器、调用约定或者底层平台。

今天要分析的是cdecl在x86机器上用visual c++ 2005上的编译结果。

首先需要设置一下项目配置以得到从源代码生成的汇编代码。

项目属性->配置属性->c/c++->输出文件->汇编输出 = Assembly With Source Code (/FAs)。

要被编译的源文件是:

分析函数调用的汇编指令分析函数调用的汇编指令Code
#include "stdafx.h"

struct Point3D
{
    int X;
    int Y;
    int Z;

    Point3D(int x, int y, int z):X(x),Y(y),Z(z)
    {}
};

Point3D AddPoint3D(Point3D p1, Point3D p2)
{
    Point3D p(p1);
    p.X += p2.X;
    p.Y += p2.Y;
    p.Z += p2.Z;

    return p;
}

void main()
{
    Point3D p1(1,2,3);
    Point3D p2(4,5,6);
    Point3D p3 = AddPoint3D(p1,p2);
}

 

生成的汇编代码是:

 

分析函数调用的汇编指令分析函数调用的汇编指令Code
分析函数调用的汇编指令; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762 
分析函数调用的汇编指令
分析函数调用的汇编指令    TITLE    d:\project\CheckAsm\CheckAsm\CheckAsm.cpp
分析函数调用的汇编指令    .686P
分析函数调用的汇编指令    .XMM
分析函数调用的汇编指令    include listing.inc
分析函数调用的汇编指令    .model    flat
分析函数调用的汇编指令
分析函数调用的汇编指令INCLUDELIB MSVCRTD
分析函数调用的汇编指令INCLUDELIB OLDNAMES
分析函数调用的汇编指令
分析函数调用的汇编指令PUBLIC    ?AddPoint3D@@YA?AUPoint3D@@U1@0@Z        ; AddPoint3D
分析函数调用的汇编指令EXTRN    @_RTC_CheckStackVars@8:PROC
分析函数调用的汇编指令EXTRN    __RTC_Shutdown:PROC
分析函数调用的汇编指令EXTRN    __RTC_InitBase:PROC
分析函数调用的汇编指令;    COMDAT rtc$TMZ
分析函数调用的汇编指令; File d:\project\checkasm\checkasm\checkasm.cpp
分析函数调用的汇编指令rtc$TMZ    SEGMENT
分析函数调用的汇编指令__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
分析函数调用的汇编指令rtc$TMZ    ENDS
分析函数调用的汇编指令;    COMDAT rtc$IMZ
分析函数调用的汇编指令rtc$IMZ    SEGMENT
分析函数调用的汇编指令__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
分析函数调用的汇编指令; Function compile flags: /Odtp /RTCsu /ZI
分析函数调用的汇编指令rtc$IMZ    ENDS
分析函数调用的汇编指令;    COMDAT ?AddPoint3D@@YA?AUPoint3D@@U1@0@Z
分析函数调用的汇编指令;上面一堆先不管
分析函数调用的汇编指令_TEXT    SEGMENT;定义PE文件中的Text段
分析函数调用的汇编指令_p$ = -16                        ; size = 12;
分析函数调用的汇编指令___$ReturnUdt$ = 8                    ; size = 4
分析函数调用的汇编指令_p1$ = 12                        ; size = 12
分析函数调用的汇编指令_p2$ = 24                        ; size = 12
分析函数调用的汇编指令;上面4个符号是AddPoint3D这个方法中的局部变量、返回值和参数的偏移量(相对于ebp)
分析函数调用的汇编指令?AddPoint3D@@YA?AUPoint3D@@U1@0@Z PROC            ; AddPoint3D, COMDAT AddPoint3D方法的定义开始,由于name mangling,名称变为了AddPoint3D@@YA?AUPoint3D@@U1@0@Z
分析函数调用的汇编指令; 15   : {
分析函数调用的汇编指令
分析函数调用的汇编指令    push    ebp;保存caller的ebp到堆栈
分析函数调用的汇编指令    mov    ebp, esp;设置本方法的ebp。ebp在方法调用的开始阶段被设置,结束阶段被还原,调用过程中保持不变。ebp表示为本次调用所分配的堆栈桢的起始地址
分析函数调用的汇编指令    sub    esp, 212                ; 000000d4H esp减少一定的数量,表示为本次调用在栈上分配了一定的空间。让我们把>ebp && <= 现在的esp 的这段内存称之为locals
分析函数调用的汇编指令    push    ebx;保存现场的3个push
分析函数调用的汇编指令    push    esi
分析函数调用的汇编指令    push    edi
分析函数调用的汇编指令    lea    edi, DWORD PTR [ebp-212];把edi设置成刚才sub esp后esp的值,也就是locals的最低地址
分析函数调用的汇编指令    mov    ecx, 53                    ; 00000035H 53 * 4 = 212, you see whats going on here?
分析函数调用的汇编指令    mov    eax, -858993460                ; ccccccccH    设置eax=cccccccch
分析函数调用的汇编指令    rep stosd ;这是一个串操作指令,其意义是
分析函数调用的汇编指令;while(ecx)
分析函数调用的汇编指令;{
分析函数调用的汇编指令;    *(int*)edi = eax;
分析函数调用的汇编指令;    edi += sizeof(int);//这里就是4
分析函数调用的汇编指令;    ecx--;
分析函数调用的汇编指令;}
分析函数调用的汇编指令;本指令和它上面的三条指令完成了把locals这段内存初始化成一片ccccccccccccccccccccc分析函数调用的汇编指令.
分析函数调用的汇编指令;当此指令执行完毕,edi == ebp
分析函数调用的汇编指令; 16   :     Point3D p(p1);
分析函数调用的汇编指令
分析函数调用的汇编指令    mov    eax, DWORD PTR _p1$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp], eax
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p1$[ebp+4]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp+4], ecx
分析函数调用的汇编指令    mov    edx, DWORD PTR _p1$[ebp+8]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp+8], edx
分析函数调用的汇编指令;复制构造局部变量p。_p1$[ebp]的意思就是[ebp + _p1$],_p1$是在前面定义过的一个偏移量
分析函数调用的汇编指令; 17   :     p.X += p2.X;
分析函数调用的汇编指令
分析函数调用的汇编指令    mov    eax, DWORD PTR _p$[ebp]
分析函数调用的汇编指令    add    eax, DWORD PTR _p2$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp], eax
分析函数调用的汇编指令
分析函数调用的汇编指令; 18   :     p.Y += p2.Y;
分析函数调用的汇编指令
分析函数调用的汇编指令    mov    eax, DWORD PTR _p$[ebp+4]
分析函数调用的汇编指令    add    eax, DWORD PTR _p2$[ebp+4]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp+4], eax
分析函数调用的汇编指令
分析函数调用的汇编指令; 19   :     p.Z += p2.Z;
分析函数调用的汇编指令
分析函数调用的汇编指令    mov    eax, DWORD PTR _p$[ebp+8]
分析函数调用的汇编指令    add    eax, DWORD PTR _p2$[ebp+8]
分析函数调用的汇编指令    mov    DWORD PTR _p$[ebp+8], eax
分析函数调用的汇编指令;这些很好理解
分析函数调用的汇编指令; 20   : 
分析函数调用的汇编指令; 21   :     return p;
分析函数调用的汇编指令
分析函数调用的汇编指令    mov    eax, DWORD PTR ___$ReturnUdt$[ebp]
分析函数调用的汇编指令;ReturnUdt中的Udt表示user defined type
分析函数调用的汇编指令;这条指令的意思是,调用方在从ebp开始偏移量是___$ReturnUdt$的dword中保存的返回值应当存放的地址,把这个地址加载到eax中
分析函数调用的汇编指令;此时eax保存的是一个地址,这个地址实际上call中局部变量p3的地址
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [eax], ecx
分析函数调用的汇编指令    mov    edx, DWORD PTR _p$[ebp+4]
分析函数调用的汇编指令    mov    DWORD PTR [eax+4], edx
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p$[ebp+8]
分析函数调用的汇编指令    mov    DWORD PTR [eax+8], ecx
分析函数调用的汇编指令;从局部变量p复制到call的局部变量p3中
分析函数调用的汇编指令    mov    eax, DWORD PTR ___$ReturnUdt$[ebp]
分析函数调用的汇编指令;在eax中保存返回值的地址
分析函数调用的汇编指令; 22   : }
分析函数调用的汇编指令;这一段{
分析函数调用的汇编指令    push    edx
分析函数调用的汇编指令    mov    ecx, ebp
分析函数调用的汇编指令    push    eax
分析函数调用的汇编指令    lea    edx, DWORD PTR $LN5@AddPoint3D
分析函数调用的汇编指令    call    @_RTC_CheckStackVars@8
分析函数调用的汇编指令    pop    eax
分析函数调用的汇编指令    pop    edx
分析函数调用的汇编指令;这一段}可以忽略掉,并不是我们程序逻辑的一部分
分析函数调用的汇编指令    pop    edi
分析函数调用的汇编指令    pop    esi
分析函数调用的汇编指令    pop    ebx
分析函数调用的汇编指令    mov    esp, ebp
分析函数调用的汇编指令    pop    ebp
分析函数调用的汇编指令    ret    0;函数返回,返回值的保存地址存放在eax中
分析函数调用的汇编指令    npad    2
分析函数调用的汇编指令$LN5@AddPoint3D:
分析函数调用的汇编指令    DD    1
分析函数调用的汇编指令    DD    $LN4@AddPoint3D
分析函数调用的汇编指令$LN4@AddPoint3D:
分析函数调用的汇编指令    DD    -16                    ; fffffff0H
分析函数调用的汇编指令    DD    12                    ; 0000000cH
分析函数调用的汇编指令    DD    $LN3@AddPoint3D
分析函数调用的汇编指令$LN3@AddPoint3D:
分析函数调用的汇编指令    DB    112                    ; 00000070H
分析函数调用的汇编指令    DB    0
分析函数调用的汇编指令?AddPoint3D@@YA?AUPoint3D@@U1@0@Z ENDP            ; AddPoint3D
分析函数调用的汇编指令_TEXT    ENDS
分析函数调用的汇编指令PUBLIC    ??0Point3D@@QAE@HHH@Z                ; Point3D::Point3D
分析函数调用的汇编指令PUBLIC    _main
分析函数调用的汇编指令EXTRN    __RTC_CheckEsp:PROC
分析函数调用的汇编指令; Function compile flags: /Odtp /RTCsu /ZI
分析函数调用的汇编指令;    COMDAT _main
分析函数调用的汇编指令_TEXT    SEGMENT
分析函数调用的汇编指令_p3$ = -56                        ; size = 12
分析函数调用的汇编指令_p2$ = -36                        ; size = 12
分析函数调用的汇编指令_p1$ = -16                        ; size = 12
分析函数调用的汇编指令_main    PROC                        ; COMDAT
分析函数调用的汇编指令
分析函数调用的汇编指令; 25   : {
分析函数调用的汇编指令;主函数的调用过程
分析函数调用的汇编指令;参见上面的注释{
分析函数调用的汇编指令    push    ebp
分析函数调用的汇编指令    mov    ebp, esp
分析函数调用的汇编指令    sub    esp, 252                ; 000000fcH
分析函数调用的汇编指令    push    ebx
分析函数调用的汇编指令    push    esi
分析函数调用的汇编指令    push    edi
分析函数调用的汇编指令    lea    edi, DWORD PTR [ebp-252]
分析函数调用的汇编指令    mov    ecx, 63                    ; 0000003fH
分析函数调用的汇编指令    mov    eax, -858993460                ; ccccccccH
分析函数调用的汇编指令    rep stosd
分析函数调用的汇编指令;参见上面的注释}
分析函数调用的汇编指令; 26   :     Point3D p1(1,2,3);
分析函数调用的汇编指令
分析函数调用的汇编指令    push    3
分析函数调用的汇编指令    push    2
分析函数调用的汇编指令    push    1
分析函数调用的汇编指令    lea    ecx, DWORD PTR _p1$[ebp];ecx传递this指针,thiscall
分析函数调用的汇编指令    call    ??0Point3D@@QAE@HHH@Z            ; Point3D::Point3D
分析函数调用的汇编指令
分析函数调用的汇编指令; 27   :     Point3D p2(4,5,6);
分析函数调用的汇编指令
分析函数调用的汇编指令    push    6
分析函数调用的汇编指令    push    5
分析函数调用的汇编指令    push    4
分析函数调用的汇编指令    lea    ecx, DWORD PTR _p2$[ebp]
分析函数调用的汇编指令    call    ??0Point3D@@QAE@HHH@Z            ; Point3D::Point3D
分析函数调用的汇编指令
分析函数调用的汇编指令; 28   :     Point3D p3 = AddPoint3D(p1,p2);
分析函数调用的汇编指令
分析函数调用的汇编指令    sub    esp, 12                    ; 0000000cH 分配实参p1的空间并按值传递
分析函数调用的汇编指令    mov    eax, esp
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p2$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [eax], ecx
分析函数调用的汇编指令    mov    edx, DWORD PTR _p2$[ebp+4]
分析函数调用的汇编指令    mov    DWORD PTR [eax+4], edx
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p2$[ebp+8]
分析函数调用的汇编指令    mov    DWORD PTR [eax+8], ecx
分析函数调用的汇编指令    sub    esp, 12                    ; 0000000cH 分配实参p2的空间并按值传递
分析函数调用的汇编指令    mov    edx, esp
分析函数调用的汇编指令    mov    eax, DWORD PTR _p1$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [edx], eax
分析函数调用的汇编指令    mov    ecx, DWORD PTR _p1$[ebp+4]
分析函数调用的汇编指令    mov    DWORD PTR [edx+4], ecx
分析函数调用的汇编指令    mov    eax, DWORD PTR _p1$[ebp+8]
分析函数调用的汇编指令    mov    DWORD PTR [edx+8], eax
分析函数调用的汇编指令    lea    ecx, DWORD PTR _p3$[ebp]
分析函数调用的汇编指令    push    ecx    ;注意这个地方,p3的地址被保存在这里,也就是返回值的地址
分析函数调用的汇编指令    call    ?AddPoint3D@@YA?AUPoint3D@@U1@0@Z    ; AddPoint3D
分析函数调用的汇编指令    add    esp, 28                    ; 0000001cH 调用方清理参数堆栈28=12+12+4
分析函数调用的汇编指令
分析函数调用的汇编指令; 29   : }
分析函数调用的汇编指令
分析函数调用的汇编指令    xor    eax, eax
分析函数调用的汇编指令    push    edx
分析函数调用的汇编指令    mov    ecx, ebp
分析函数调用的汇编指令    push    eax
分析函数调用的汇编指令    lea    edx, DWORD PTR $LN7@main
分析函数调用的汇编指令    call    @_RTC_CheckStackVars@8
分析函数调用的汇编指令    pop    eax
分析函数调用的汇编指令    pop    edx
分析函数调用的汇编指令    pop    edi
分析函数调用的汇编指令    pop    esi
分析函数调用的汇编指令    pop    ebx
分析函数调用的汇编指令    add    esp, 252                ; 000000fcH
分析函数调用的汇编指令    cmp    ebp, esp
分析函数调用的汇编指令    call    __RTC_CheckEsp
分析函数调用的汇编指令    mov    esp, ebp
分析函数调用的汇编指令    pop    ebp
分析函数调用的汇编指令    ret    0
分析函数调用的汇编指令    npad    3
分析函数调用的汇编指令$LN7@main:
分析函数调用的汇编指令    DD    3
分析函数调用的汇编指令    DD    $LN6@main
分析函数调用的汇编指令$LN6@main:
分析函数调用的汇编指令    DD    -16                    ; fffffff0H
分析函数调用的汇编指令    DD    12                    ; 0000000cH
分析函数调用的汇编指令    DD    $LN3@main
分析函数调用的汇编指令    DD    -36                    ; ffffffdcH
分析函数调用的汇编指令    DD    12                    ; 0000000cH
分析函数调用的汇编指令    DD    $LN4@main
分析函数调用的汇编指令    DD    -56                    ; ffffffc8H
分析函数调用的汇编指令    DD    12                    ; 0000000cH
分析函数调用的汇编指令    DD    $LN5@main
分析函数调用的汇编指令$LN5@main:
分析函数调用的汇编指令    DB    112                    ; 00000070H
分析函数调用的汇编指令    DB    51                    ; 00000033H
分析函数调用的汇编指令    DB    0
分析函数调用的汇编指令$LN4@main:
分析函数调用的汇编指令    DB    112                    ; 00000070H
分析函数调用的汇编指令    DB    50                    ; 00000032H
分析函数调用的汇编指令    DB    0
分析函数调用的汇编指令$LN3@main:
分析函数调用的汇编指令    DB    112                    ; 00000070H
分析函数调用的汇编指令    DB    49                    ; 00000031H
分析函数调用的汇编指令    DB    0
分析函数调用的汇编指令_main    ENDP
分析函数调用的汇编指令; Function compile flags: /Odtp /RTCsu /ZI
分析函数调用的汇编指令_TEXT    ENDS
分析函数调用的汇编指令;    COMDAT ??0Point3D@@QAE@HHH@Z
分析函数调用的汇编指令_TEXT    SEGMENT
分析函数调用的汇编指令_this$ = -8                        ; size = 4
分析函数调用的汇编指令_x$ = 8                            ; size = 4
分析函数调用的汇编指令_y$ = 12                        ; size = 4
分析函数调用的汇编指令_z$ = 16                        ; size = 4
分析函数调用的汇编指令??0Point3D@@QAE@HHH@Z PROC                ; Point3D::Point3D, COMDAT
分析函数调用的汇编指令; _this$ = ecx
分析函数调用的汇编指令
分析函数调用的汇编指令; 11   :     {}
分析函数调用的汇编指令
分析函数调用的汇编指令    push    ebp
分析函数调用的汇编指令    mov    ebp, esp
分析函数调用的汇编指令    sub    esp, 204                ; 000000ccH
分析函数调用的汇编指令    push    ebx
分析函数调用的汇编指令    push    esi
分析函数调用的汇编指令    push    edi
分析函数调用的汇编指令    push    ecx
分析函数调用的汇编指令    lea    edi, DWORD PTR [ebp-204]
分析函数调用的汇编指令    mov    ecx, 51                    ; 00000033H
分析函数调用的汇编指令    mov    eax, -858993460                ; ccccccccH
分析函数调用的汇编指令    rep stosd
分析函数调用的汇编指令    pop    ecx
分析函数调用的汇编指令    mov    DWORD PTR _this$[ebp], ecx
分析函数调用的汇编指令    mov    eax, DWORD PTR _this$[ebp]
分析函数调用的汇编指令    mov    ecx, DWORD PTR _x$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [eax], ecx
分析函数调用的汇编指令    mov    eax, DWORD PTR _this$[ebp]
分析函数调用的汇编指令    mov    ecx, DWORD PTR _y$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [eax+4], ecx
分析函数调用的汇编指令    mov    eax, DWORD PTR _this$[ebp]
分析函数调用的汇编指令    mov    ecx, DWORD PTR _z$[ebp]
分析函数调用的汇编指令    mov    DWORD PTR [eax+8], ecx
分析函数调用的汇编指令    mov    eax, DWORD PTR _this$[ebp]
分析函数调用的汇编指令    pop    edi
分析函数调用的汇编指令    pop    esi
分析函数调用的汇编指令    pop    ebx
分析函数调用的汇编指令    mov    esp, ebp
分析函数调用的汇编指令    pop    ebp
分析函数调用的汇编指令    ret    12                    ; 0000000cH
分析函数调用的汇编指令??0Point3D@@QAE@HHH@Z ENDP                ; Point3D::Point3D
分析函数调用的汇编指令_TEXT    ENDS
分析函数调用的汇编指令END
分析函数调用的汇编指令

That's it.

转载于:https://www.cnblogs.com/zhy2002/archive/2008/12/10/1351796.html

上一篇:某桌球辅助登录算法分析并转本地验证


下一篇:用汇编的眼光看C++(之指针1)