当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++基础入门教程

从汇编代码看c++的晚捆绑

    把函数体同调用相联系成为捆绑。但捆绑在运行前发生成为早捆绑。晚捆绑又称为动态捆绑或运行时捆绑。


    c++代码为:
    class base {
    int i;
    public:
    virtual void print() {
    }
    };
    class derived : public base {
    int j;
    public:
    void print() {
    }

    virtual void print_another() {
    }
    };

    int main()
    {
    base* b = new derived;
    b->print();
    return 0;
    }

    生成的汇编代码为:

    TITLE D:\code\th_in_c++\pvdest\pvdest.cpp
    .386P
    include listing.inc
    if @Version gt 510
    .model FLAT
    else
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    _DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
    _DATA ENDS
    CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
    CONST ENDS
    _BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
    _BSS ENDS
    $$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
    $$SYMBOLS ENDS
    $$TYPES SEGMENT BYTE USE32 'DEBTYP'
    $$TYPES ENDS
    _TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
    _TLS ENDS
    ; COMDAT ?print@base@@UAEXXZ
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT ?print@derived@@UAEXXZ
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT ?print_another@derived@@UAEXXZ
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT _main
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT ??0derived@@QAE@XZ
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT ??0base@@QAE@XZ
    _TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
    _TEXT ENDS
    ; COMDAT ??_7base@@6B@
    CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
    CONST ENDS
    ; COMDAT ??_7derived@@6B@
    CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
    CONST ENDS
    FLAT GROUP _DATA, CONST, _BSS
    ASSUME CS: FLAT, DS: FLAT, SS: FLAT
    endif
    PUBLIC ??0derived@@QAE@XZ ; derived::derived
    PUBLIC _main
    EXTRN ??2@YAPAXI@Z:NEAR ; operator new
    EXTRN ??3@YAXPAX@Z:NEAR ; operator delete
    EXTRN __chkesp:NEAR
    EXTRN __except_list:DWORD
    EXTRN ___CxxFrameHandler:NEAR
    ; COMDAT xdata$x
    ; File D:\code\th_in_c++\pvdest\pvdest.cpp
    xdata$x SEGMENT
    __ehfuncinfo$_main DD 019930520H
    DD 01H
    DD FLAT:__unwindtable$_main
    DD 2 DUP(00H)
    DD 2 DUP(00H)
    ORG $+4
    __unwindtable$_main DD 0ffffffffH
    DD FLAT:__unwindfunclet$_main
    xdata$x ENDS
    ; COMDAT _main
    _TEXT SEGMENT
    _b$ = -16
    $T270 = -20
    $T271 = -24
    __$EHRec$ = -12
    _main PROC NEAR ; COMDAT
    ; File D:\code\th_in_c++\pvdest\pvdest.cpp
    ; Line 22
    push ebp
    mov ebp, esp
    push -1
    push __ehhandler$_main
    mov eax, DWORD PTR fs:__except_list
    push eax
    mov DWORD PTR fs:__except_list, esp
    sub esp, 80 ; 00000050H
    push ebx
    push esi
    push edi
    lea edi, DWORD PTR [ebp-92]
    mov ecx, 20 ; 00000014H
    mov eax, -858993460 ; ccccccccH
    rep stosd
    ; Line 23
    push 12 ; 0000000cH
    call ??2@YAPAXI@Z ; operator new
    add esp, 4
    mov DWORD PTR $T271[ebp], eax
    mov DWORD PTR __$EHRec$[ebp+8], 0
    cmp DWORD PTR $T271[ebp], 0
    je SHORT $L272
    mov ecx, DWORD PTR $T271[ebp] //通过ecs将分配给derived对象b的地址传给构造函数
    call ??0derived@@QAE@XZ ; derived::derived //调用构造函数
    mov DWORD PTR -28+[ebp], eax //保存对象b的_this指针
    jmp SHORT $L273
    $L272:
    mov DWORD PTR -28+[ebp], 0
    $L273:
    mov eax, DWORD PTR -28+[ebp] //将对象b的_this指针取到EAX
    mov DWORD PTR $T270[ebp], eax //将EAX保存到$T270[ebp]中
    mov DWORD PTR __$EHRec$[ebp+8], -1
    mov ecx, DWORD PTR $T270[ebp] //_this指针取到ecs
    mov DWORD PTR _b$[ebp], ecx //保存到_b$[ebp}内
    ; Line 24
    mov edx, DWORD PTR _b$[ebp] //_this指针取到edx;
    mov eax, DWORD PTR [edx] //该对象中存放的第一个数据vftable的地址取到eax
    mov esi, esp //?
    mov ecx, DWORD PTR _b$[ebp] //传递_this指针
    call DWORD PTR [eax]       //通过vftable中存放的print函数的地址调用print
    cmp esi, esp //?
    call __chkesp //?
    ; Line 25
    xor eax, eax
    ; Line 26
    mov ecx, DWORD PTR __$EHRec$[ebp]
    mov DWORD PTR fs:__except_list, ecx
    pop edi
    pop esi
    pop ebx
    add esp, 92 ; 0000005cH
    cmp ebp, esp
    call __chkesp
    mov esp, ebp
    pop ebp
    ret 0
    _TEXT ENDS
    ; COMDAT text$x
    text$x SEGMENT
    __unwindfunclet$_main:
    mov eax, DWORD PTR $T271[ebp]
    push eax
    call ??3@YAXPAX@Z ; operator delete
    pop ecx
    ret 0
    __ehhandler$_main:
    mov eax, OFFSET FLAT:__ehfuncinfo$_main
    jmp ___CxxFrameHandler
    text$x ENDS
    _main ENDP
    PUBLIC ??0base@@QAE@XZ ; base::base
    PUBLIC ?print@derived@@UAEXXZ ; derived::print
    PUBLIC ?print_another@derived@@UAEXXZ ; derived::print_another
    PUBLIC ??_7derived@@6B@ ; derived::`vftable'
    ; COMDAT ??_7derived@@6B@
    CONST SEGMENT
    ??_7derived@@6B@ DD FLAT:?print@derived@@UAEXXZ ; derived::`vftable'
    DD FLAT:?print_another@derived@@UAEXXZ
    CONST ENDS
    ; COMDAT ??0derived@@QAE@XZ
    _TEXT SEGMENT
    _this$ = -4
    ??0derived@@QAE@XZ PROC NEAR ; derived::derived, COMDAT
    push ebp
    mov ebp, esp
    sub esp, 68 ; 00000044H
    push ebx
    push esi
    push edi
    push ecx
    lea edi, DWORD PTR [ebp-68]
    mov ecx, 17 ; 00000011H
    mov eax, -858993460 ; ccccccccH
    rep stosd
    pop ecx
    mov DWORD PTR _this$[ebp], ecx //对象存储区域的开始位置通过ecs传给_this指针
    mov ecx, DWORD PTR _this$[ebp] //传递_this指针
    call ??0base@@QAE@XZ ; base::base       //调用base的构造函数进行初始化
    mov eax, DWORD PTR _this$[ebp]
 

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接