2016-05-09 30 views
1

以下はC++のソースコードです。コードにはHumanBeingクラスがあり、DisplayとVerify関数があります。各関数はステートメントを出力します。C++コードのアセンブリコードでstatic_initialization_and_destructionと_GLOBAL__sub_I_main関数の目的はありますか?

#include <iostream> 

using namespace std; 

class HumanBeing{ 
    public : 
     void display() { 
      cout << "hello aam a human being" << endl; 
    } 
     void print() { 

     cout << "verify print" << endl; 
} 

}; 

int main() 
{ 
HumanBeing vamshi; 

vamshi.display(); 
vamshi.print(); 
return 0; 
} 

これは、このコードでは上記のC++コード

 .file "verify.cpp" 
     .local _ZStL8__ioinit 
     .comm _ZStL8__ioinit,1,1 
     .section  .rodata 
.LC0: 
     .string "hello aam a human being" 
     .section  .text._ZN10HumanBeing7displayEv,"axG",@progbits,_ZN10HumanBeing7displayEv,comdat 
     .align 2 
     .weak _ZN10HumanBeing7displayEv 
     .type _ZN10HumanBeing7displayEv, @function 
_ZN10HumanBeing7displayEv: 
.LFB971: 
     .cfi_startproc 
     pushq %rbp 
     .cfi_def_cfa_offset 16 
     .cfi_offset 6, -16 
     movq %rsp, %rbp 
     .cfi_def_cfa_register 6 
     subq $16, %rsp 
     movq %rdi, -8(%rbp) 
     movl $.LC0, %esi 
     movl $_ZSt4cout, %edi 
     call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc 
     movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi 
     movq %rax, %rdi 
     call _ZNSolsEPFRSoS_E 
     leave 
     .cfi_def_cfa 7, 8 
     ret 
     .cfi_endproc 
.LFE971: 
     .size _ZN10HumanBeing7displayEv, .-_ZN10HumanBeing7displayEv 
     .section  .rodata 
.LC1: 
     .string "verify print" 
     .section  .text._ZN10HumanBeing5printEv,"axG",@progbits,_ZN10HumanBeing5printEv,comdat 
     .align 2 
     .weak _ZN10HumanBeing5printEv 
     .type _ZN10HumanBeing5printEv, @function 
_ZN10HumanBeing5printEv: 
.LFB972: 
     .cfi_startproc 
     pushq %rbp 
     .cfi_def_cfa_offset 16 
     .cfi_offset 6, -16 
     movq %rsp, %rbp 
     .cfi_def_cfa_register 6 
     subq $16, %rsp 
     movq %rdi, -8(%rbp) 
     movl $.LC1, %esi 
     movl $_ZSt4cout, %edi 
     call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc 
     movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi 
     movq %rax, %rdi 
     call _ZNSolsEPFRSoS_E 
     leave 
     .cfi_def_cfa 7, 8 
     ret 
     .cfi_endproc 
.LFE972: 
     .size _ZN10HumanBeing5printEv, .-_ZN10HumanBeing5printEv 
     .text 
     .globl main 
     .type main, @function 
main: 
.LFB973: 
     .cfi_startproc 
     pushq %rbp 
     .cfi_def_cfa_offset 16 
     .cfi_offset 6, -16 
     movq %rsp, %rbp 
     .cfi_def_cfa_register 6 
     subq $16, %rsp 
     leaq -1(%rbp), %rax 
     movq %rax, %rdi 
     call _ZN10HumanBeing7displayEv 
     leaq -1(%rbp), %rax 
     movq %rax, %rdi 
     call _ZN10HumanBeing5printEv 
     movl $0, %eax 
     leave 
     .cfi_def_cfa 7, 8 
     ret 
     .cfi_endproc 
.LFE973: 
     .size main, .-main 
     .type _Z41__static_initialization_and_destruction_0ii, @function 
_Z41__static_initialization_and_destruction_0ii: 
.LFB982: 
     .cfi_startproc 
     pushq %rbp 
     .cfi_def_cfa_offset 16 
     .cfi_offset 6, -16 
     movq %rsp, %rbp 
     .cfi_def_cfa_register 6 
     subq $16, %rsp 
     movl %edi, -4(%rbp) 
     movl %esi, -8(%rbp) 
     cmpl $1, -4(%rbp) 
     jne  .L5 
     cmpl $65535, -8(%rbp) 
     jne  .L5 
     movl $_ZStL8__ioinit, %edi 
     call _ZNSt8ios_base4InitC1Ev 
     movl $__dso_handle, %edx 
     movl $_ZStL8__ioinit, %esi 
     movl $_ZNSt8ios_base4InitD1Ev, %edi 
     call __cxa_atexit 
.L5: 
     leave 
     .cfi_def_cfa 7, 8 
     ret 
     .cfi_endproc 
.LFE982: 
     .size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii 
     .type _GLOBAL__sub_I_main, @function 
_GLOBAL__sub_I_main: 
.LFB983: 
     .cfi_startproc 

の対応するアセンブリコードでは、私は、次の疑問ています

1.static_initialization_and_destructionが - 、機能のようですが、 GLOBAL__sub_I_main関数の目的と動作は明確ではありません。GLOBAL__sub_I_main関数の目的と動作は明確ではありません。

  1. はっきりと理解される。

GLOBAL__sub_I_main関数のこのコードと目的で、コンストラクタとデストラクタの作業と構成を誰かが明確に説明できますか?

答えて

4

両方の関数は、mainの前に構築する必要があるスタティックな保存期間を持つインスタンス化されたクラスに対して、C++でgccによって使用されます。

  • コール前処理/コンパイルされたC++ソースファイル(必須)
  • 登録静的記憶期間を持つクラスの任意のコンストラクタ(__static_initialization_and_destruction_0(int, int)を復号化され)

    class A { 
        A(); 
        ~A(); 
        ... 
    }; 
    
    A a; 
    
    // "a" will need to be constructed before main 
    int main() 
    { 
        return a.Foo(); 
    } 
    // "a" will need to be destructed after main 
    

    発生_Z41__static_initialization_and_destruction_0ii関数が2つの目的を果たします事前処理された/コンパイルされたC++ソースファイル(必要な場合)内の静的な記憶期間を持つクラスのデストラクタは、終了関数としてatexitを使用します。

_GLOBAL__sub_I_mainは、関数ポインタが.init_arrayセクションに追加された単純なラッパー関数です。複数のソースファイルをコンパイルすると、個々のオブジェクトファイルは.init_arrayに初期化関数を追加し、mainが呼び出される前にすべての関数が呼び出されます。

これはすぐにはわかりませんが、コードには静的な保存期間のあるインスタンスが含まれています。 <iostream>ヘッダーファイルは、静的オブジェクトのコンストラクターとデストラクタの標準I/Oストリームに安全にアクセスできるように、できるだけ早く構築する必要があるstd::ios_base::Initを宣言します。

関連する問題