和
作業系統之前的程式 (1) - c++ 篇的差別是只把 Io io 搬到 WinMain 的外面, 但結果可是大大不同。
ld -m elf_i386 -static -Tcpp.ld -nostdlib -M -o cppb.elf cppb.o io.o > cb.elf.map
ld: section .sig loaded at [0000000000007dfe,0000000000007dff] overlaps section .rodata loaded at [0000000000007df4,0000000000007e21]
cppb.o: In function `__static_initialization_and_destruction_0':
/home/descent/test/simple_os.test/c-bootloader/cpp/cppb.cpp:18: undefined reference to `__cxa_atexit'
make: *** [cppb.elf] Error 1
12 void *__dso_handle;
13 int __cxa_atexit(void (*destructor) (void *), void *arg, void *__dso_handle)
14 {
15 return 0;
16 }
18 Io io;
為了使用 global object 要補上 __cxa_atexit (註冊 dtor 用), __dso_handle (dynamic share object 相關), 這樣 link, compile 才會過。而令人害怕的是:
__static_initialization_and_destruction_0
我的 c++ 程式碼根本沒有這行 (要不是忘記 extern "C", 我可能沒發現, 不過用 objdump 還是可以看到), 所以肯定是 g++ 幹的好事。只不過把 io 宣告成 global object, 就發生了這麼大的差異。c++ 編譯器果然幹了不少事情, 也讓這支程式大於 512 byte, 看吧! c++ 的程式絕對不是大假的。
還有這個 _GLOBAL__I_io 也是 g++ 產生的。
_GLOBAL__I_io, __static_initialization_and_destruction_0 是幹嘛用的? 請參考:
c++ runtime - global object ctor (0)
objdump 為我們帶來一些資訊:
33 00000142 <_Z41__static_initialization_and_destruction_0ii>:
58 00000196 <_GLOBAL__I_io>:
原來是讓 _GLOBAL__I_io> call 的 (這是 16bit code, 所以使用 -m i8086 會得到比較正確的反組譯結果)。
這是額外產生的程式碼, 當然還有不知道為什麼有兩份的 ctor/dtor。其他的不用看, 那是我拿來佔版面用的。
global_object$ c++filt _Z41__static_initialization_and_destruction_0ii
__static_initialization_and_destruction_0(int, int)
c++filt 可以 demangle 還原本來的 symbol。
_GLOBAL__I_io 用猜的都能感覺出來是 global io 的 ctor, 不過要怎麼證明呢?等我證明之後會有下一篇 (沒有下一篇的話就是我錯了或是還沒證明出來 XD)。
還真的搞錯了, 和我想的不太一樣。ref:
c++ runtime - global object ctor (0)
-rwxr-xr-x 1 descent descent 556 2012-08-08 13:31 cppb.bin
-rwxr-xr-x 1 descent descent 4979 2012-08-08 13:31 cppb.elf
由於超過 512, 所以我改到 msdos 下執行。
顛覆 c++ 程式員的想像, ctor/dtor 完全沒執行 (請對照
作業系統之前的程式 (1) - c++ 篇執行畫面)。
從這篇開始, 標題要改成 c++ runtime, 畢竟這是 os 下的程式, 無法再稱為作業系統之前的程式。
這是 g++ 4.4.3 的結果, g++ (Debian 4.7.0-9) 4.7.0 又不一樣了。不要整我啦!
自己對, 我不解說了。
ref:
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。