} } }

    从汇编看c++中参数对象和局部对象的析构次序

    添加时间:2013-5-14 点击量:

    下面是c++的源码:



    class X  {
    
    public:
    int i;
    int j;
    ~X() {}

    };
    void f(X x) {
    X x1;
    x.i
    = 1;
    x.j
    = 2;

    }
    int main() {
    f(X());
    }



    下面是main函数的汇编码:



    _main    PROC
    

    ; 15 : int main() {

    push ebp
    mov ebp, esp
    sub esp, 8;为姑且对象预留8byte空间,因为没有显示定义机关函数,
    ;并且这种景象下编译器供给无用的默认机关函数,是以看不到机关函数的调用

    ; 16 : f(X());

    mov eax, DWORD PTR ¥T2560[ebp+4];将偏移姑且变量的首地址4byte处内存中内容给eax,即将姑且变量的成员变量j值给eax
    push eax;将eax压栈
    mov ecx, DWORD PTR ¥T2560[ebp];将姑且变量首地址中的内容给ecx,即将姑且变量中的成员变量i值给ecx
    push ecx;将ecx压栈
    ;上方四句创建了姑且变量的一份拷贝,作为参数调用f
    call ?f@@YAXVX@@@Z ; 调用函数f
    add esp, 8;将栈顶指针下移8byte,开释为参数对象的供给的栈空间
    lea ecx, DWORD PTR ¥T2560[ebp];将姑且对象的首地址给ecx
    call ??1X@@QAE@XZ ; 为姑且对象调用析构函数

    ; 17 : }

    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0
    _main ENDP


    从上方可以看出,产生的姑且对象在函数调用完成退出后才调用析构函数。


    下面是f函数的汇编码:



    ?f@@YAXVX@@@Z PROC                    ; f
    

    ; 9 : void f(X x) {

    push ebp
    mov ebp, esp
    sub esp, 8;为局部对象x1预留8byte的空间

    ; 10 : X x1;
    ;
    11 : x.i = 1;

    mov DWORD PTR _x¥[ebp], 1;把1写给参数对象首地址处,即把1写入参数对象的成员变量i

    ; 12 : x.j = 2;

    mov DWORD PTR _x¥[ebp+4], 2;把2写入偏移参数对象首地址4byte处的内存,即把2写入参数对象的成员变量j

    ; 13 :
    ;
    14 : }

    lea ecx, DWORD PTR _x1¥[ebp];将局部变量x1的首地址给ecx
    call ??1X@@QAE@XZ ; 为x1调用析构函数
    lea ecx, DWORD PTR _x¥[ebp];将参数对象的首地址给ecx
    call ??1X@@QAE@XZ ; 为参数对象调用析构函数
    mov esp, ebp
    pop ebp
    ret 0
    ?f@@YAXVX@@@Z ENDP
    ; f
    ;
    Function compile flags: /Odtp
    _TEXT ENDS
    ; COMDAT ??1X@@QAE@XZ
    _TEXT SEGMENT
    _this¥ = -
    4 ; size = 4
    ??1X@@QAE@XZ PROC ; X::~X, COMDAT
    ;
    _this¥ = ecx

    ; 6 : ~X() {}

    push ebp
    mov ebp, esp
    push ecx
    mov DWORD PTR _this¥[ebp], ecx
    mov esp, ebp
    pop ebp
    ret 0
    ??1X@@QAE@XZ ENDP


    从上方的代码可以看出,参数对象和局部对象都是在函数退出之前调用析构函数。并且参数对象在局部对象调用析构函数之后再调用本身的析构函数。


    容易发怒的意思就是: 别人做了蠢事, 然后我们代替他们, 表现出笨蛋的样子。—— 蔡康永
    分享到: