The following is the C++ source code. The code has a class HumanBeing and with Display and verify functions. Each function prints statements.
#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;
}
This is the corresponding assembly code of the above c++ code
.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
In this code the I have the following doubts:
1.static_initialization_and_destruction -- seems to be function, but its exact working is not clearly understood
Could anyone clearly explain the working and organisation of constructor and destructor in this code and purpose of GLOBAL__sub_I_main function ?
Both functions are used by gcc in C++ for any instantiated classes with static storage duration that need to be constructed before main e.g.
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
The generated _Z41__static_initialization_and_destruction_0ii
function (demangled __static_initialization_and_destruction_0(int, int)
) serves 2 purposes:
_GLOBAL__sub_I_main
is a simple wrapper function around it, who's function-pointer is added to the .init_array
section. When compiling multiple source files, each individual object file will add initialization functions to the .init_array
and all of those functions will be called before main
is called.
While this may not be immediately obvious your code contains an instance with static storage duration. The <iostream>
header file declares std::ios_base::Init which needs to be constructed as early as possible to make it safe to access the standard I/O streams in the constructors and destructors of static objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With