2016-05-09 37 views
1

以下是C++源代碼。該代碼具有HumanBeing類以及顯示和驗證功能。每個函數都打印語句。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 - 似乎是函數,但其確切的工作不明確

  1. 目的和GLOBAL__sub_I_main函數的工作不是清楚地理解。

任何人都可以清楚地解釋在這段代碼中的構造函數和析構函數的工作和組織以及GLOBAL__sub_I_main函數的用途嗎?

回答

4

這兩個函數都被C++中的gcc用於任何具有靜態存儲持續時間的實例化類,這些靜態存儲持續時間需要在主要構造之前構建。

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函數(demangled __static_initialization_and_destruction_0(int, int))用於2個用途:

  • 呼叫的類與預處理/編譯的C++源文件中的靜態存儲的持續時間(當需要時)
  • 註冊任何構造通過atexit將預處理/編譯後的C++源文件中的靜態存儲持續時間的類的析構函數(需要時)用作退出函數。

_GLOBAL__sub_I_main是一個簡單的包裝函數,它的功能指針被添加到.init_array部分。在編譯多個源文件時,每個單獨的目標文件都會向.init_array添加初始化函數,並且在調用main之前將調用所有這些函數。

雖然這可能不會立即顯而易見,但您的代碼包含一個具有靜態存儲持續時間的實例。 <iostream>頭文件聲明std::ios_base::Init需要儘早構建,以便安全地訪問靜態對象的構造函數和析構函數中的標準I/O流。