env: g++ 4.7.1
local static object 比起 global object 複雜多了 (因為 global object 要做的事情 local static object 都要做), 我真的還要花心力在這上面嗎?我猶豫了, 很怕這是個無底洞。畢竟我想完成的是 os, 沒有一定要用 c++ 來完成。除了參考 osdev 上的文章之外, 幾乎都靠自己使用 objdump, nm, readelf 這些工具辛苦的查探。看著我不熟悉的組合語言, 這真的很辛苦, 而為了不讓辛苦的查探白費, 我又得更辛苦的紀錄下來。
而說實在的, 除了滿足我自己的求知慾望之外, 似乎對我沒什麼幫助, 我又不會寫 c++ compiler。不過像驢子般的耐力似乎是我的優點之一, 最後我還是決定繼續下去, 又由於我已經搞清楚了, 所以再 blog 一篇。若你願意看這篇文章, 那真是讓我高興, 我的文筆並不那麼優秀, 所以我知道這並不是很好讀。
以下是相關 c++ 程式碼:
static object 除了和 global object 一樣要自己補上
int __cxa_atexit(void (*destructor) (void *), void *arg, void *__dso_handle)
__dso_handle
還需要補上
int __cxa_guard_acquire()
int __cxa_guard_release()
ref: cpp_abi.cpp L56 ~ L64, function prototype 我是亂寫的 (其實是錯的), 不過這不是這篇的重點, 化繁為簡才容易搞懂。
12 1ef: 66 e8 c3 02 00 00 calll 4b8 <__cxa_guard_acquire>
22 217: 66 e8 aa 02 00 00 calll 4c7 <__cxa_guard_release>
這便是我們補上的那兩個 function。只要宣告了 local static object, g++ 便會為我們
生成產生
調用呼叫這兩個 function 的程式碼。哇!真是邪惡, 我們應當習慣這件事情了。
12 1ef: 66 e8 c3 02 00 00 calll 4b8 <__cxa_guard_acquire>
13 1f5: 66 85 c0 test %eax,%eax
14 1f8: 0f 95 c0 setne %al
15 1fb: 84 c0 test %al,%al
16 1fd: 74 41 je 240 <cpp_main+0x74>
17 1ff: 67 66 c7 04 24 c8 07 movl $0x7c8,(%eax,%eax,1)
18 206: 00 00
19 208: 66 e8 3e 00 00 00 calll 24c <_ZN2IoC1Ev>
從這裡可以看出會判斷 int __cxa_guard_acquire() 的傳回值 (compare %eax, function 的傳回值會紀錄在 %eax, L13 ~ 16), 所以要 return 1 才會 call L19 的 Io::Io(), 我一開始 return 0, 結果 Io::Io() 一直沒被呼叫, 看了反組譯的組合語言之後才理解。
我不貼執行結果了, 如果你跟著我的一系列文章到這裡, 應該可以自己完成測試, 如果不行, 我相信你應該會問我如何做這樣的測試, 我很樂意回答這樣的問題。
static object 這樣就結束了嗎? 當然沒這麼簡單, 這只是能讓 g++ 編譯器編譯過而已, 行為不是正確的, 還會有《
c++ runtime - static object (1)》。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。