Cedric Martens
Cedric Martens

Reputation: 1199

Why is a global variable initialized with a function after the main label in assembly?

This example is with clang 15 using -O3.

Check it out on Godbolt: https://godbolt.org/z/Pd31fGKTe

#include <iostream>

int hello = printf("Hello World!\n");

int main() {
    printf("main()");
}

Output is as expected from the rules of C++ initialization.

Hello World!
main()

What is not expected to me is the assembly code:

main:                                   # @main
        push    rax
        lea     rdi, [rip + .L.str.2]
        xor     eax, eax
        call    printf@PLT
        xor     eax, eax
        pop     rcx
        ret
_GLOBAL__sub_I_example.cpp:             # @_GLOBAL__sub_I_example.cpp
        push    rbx
        lea     rbx, [rip + std::__ioinit]
        mov     rdi, rbx
        call    std::ios_base::Init::Init()@PLT
        mov     rdi, qword ptr [rip + std::ios_base::Init::~Init()@GOTPCREL]
        lea     rdx, [rip + __dso_handle]
        mov     rsi, rbx
        call    __cxa_atexit@PLT
        lea     rdi, [rip + .L.str]
        xor     eax, eax
        call    printf@PLT
        mov     dword ptr [rip + hello], eax
        pop     rbx
        ret
hello:
        .long   0                               # 0x0

.L.str:
        .asciz  "Hello World!\n"

.L.str.2:
        .asciz  "main()"

It seems to me that main: is not the entry point, but _GLOBAL__sub_I_example.cpp: instead. I believe this because if not I think the program would ouput main() first, but it doesn't. What confuses me is that I don't get how the code from the main: label gets called. If _GLOBAL__sub_I_example.cpp: is the entry point, then why does it return something and how does the program ever run the code with the main label.

Upvotes: 3

Views: 246

Answers (0)

Related Questions