這是
作業系統之前的程式 (0) - hello XYZ的 c++ 版本。
作業系統之前的程式 (0) - hello XYZ這是在
mosut 分享的一個主題。後來補充了 c++ 版本, 示範了預設參數的 function c++ 語言特性。
不過 c++ 主要的 class 特性若不能使用, 會使得 c++ 的能力大大失色 (和 c 相差不遠), 這次的分享就是來使用 c++ 的 class。
|
fig 1 在真實機器上測試 |
一直以來都很喜歡 c++ 這個語言, simple os 很想用 c++ 來完成, 無奈實在不知道如何實作 c++ runtime, 目前透過 ref 1 可以完成到這樣的階段 (我找到這資料時, 你可以想像到我有多興奮)。c++ 有很多豐富的特性, 有些需要 c++ runtime 來實作, 目前這版本只能做到這樣, 千萬別帥氣的把 rtti, exception 這樣的語法帶入, 肯定會失敗的, 也無法使用 global/static object。global object 還好, 很多書籍都告知要少用 global object, static object 嘛 ... 那就真的沒辦法了。
c++ 似乎帶給某些程式員效率低下的錯覺, 沒錯, 要使用某些語言特性, 像是 rtti, exception 是會有額外負擔的, 「要馬兒好又要馬兒到對方陣營偷糧草」這樣的事情是不存在的。
不過以這個例子來說, 是和 c 一樣快的。ctor/dtor 並沒有帶來效率上的額外負擔, 不過由於在 ctor 需要使用 exception handle 來處理錯誤, 所以正常的 ctor, 應該會有額外的負擔。這負擔有多大呢?我不清楚, 我還不會處理 exception handle runtime, 距離這篇文章四年之後 (真的是好久), 我寫了以下幾篇關於 exception handle 的文章:
但程式是自己寫的, 可以用某些方法迴避使用 exception handle。
-fno-exceptions 一定需要, 要不然會需要這個 symbol __gxx_personality_v0 需要 link -lstdc++(你應該不會預期可以 link stdc++ 吧?), 在 os 之前的 c++ 要使用 exception, 得自己提供這段程式碼。
喜歡語言評論的朋友可以參考:
我喜歡其中的一句話: 「由於 c++ 和 c 真的很像, 有人把 c 的坑也算到 c++頭上了」XD
和之前一樣, 列出所有檔案以其 linker script, 從程式來看就和一般 os 下的 c++ 程式一樣, 有變化的一樣是編譯流程。
g++ -m32 -g -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector -c -o cppb.o cppb.cpp
g++ -m32 -g -Wall -Wextra -Werror -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector -c -o io.o io.cpp
ld -m elf_i386 -static -Tcpp.ld -nostdlib -M -o cppb.elf cppb.o io.o > cb.elf.map
objcopy -R .pdr -R .comment -R.note -S -O binary cppb.elf cppb.bin
dd if=/dev/zero of=floppy.img skip=1 seek=1 bs=512 count=2879
dd if=cppb.bin of=floppy.img bs=1 count=512 conv=notrunc
qemu -fda floppy.img
除了使用 qemu 來測試, 大多數也會用實機來測試, 之前實在吃過太多苦頭, 沒有實機測試過, 真的不放心。
取得本文的程式碼:
git clone git@github.com:descent/simple_os.git
cd simple_os
git checkout origin/cpp_bootloader -b cpp_bootloader
以下是把 io object 宣告為 global 和 static 的錯誤訊息 (早就說過不行了, 還要試, A ... 理論是理論, 總是要驗證一下才是)。
不好搞, 沒錯吧?
ref:
https://www.google.com/search?q=__cxa_atexit+osdev+c%2B%2B&ie=utf-8&oe=utf-8&client=ubuntu&channel=fs
23: 00007ca4 83 FUNC GLOBAL DEFAULT 1 _ZN2IoC1Ev
15: 00007c50 83 FUNC GLOBAL DEFAULT 1 _ZN2IoC2Ev
27: 00007d20 39 FUNC GLOBAL DEFAULT 1 _ZN2IoD1Ev
17: 00007cf8 39 FUNC GLOBAL DEFAULT 1 _ZN2IoD2Ev
26: 00007d48 68 FUNC GLOBAL DEFAULT 1 _ZN2Io5printEPKc
紅色的 c++ mangling 意思請參考 (這也是 c++ ABI 不相容的原因之一):
http://mentorembedded.github.com/cxx-abi/abi-mangling.html
對一下應該勉強看得懂。
C1, C2 是 constructor
D1, D2 是 destructor
雖然執行速度和 c 一樣, 不過大小好像比 c 大了點。ctor/dtor 竟然要兩份。不懂阿 ...
ref:
- http://wiki.osdev.org/C%2B%2B_Bare_Bones
- http://wiki.osdev.org/C%2B%2B
- C++ Bare Bones
- C++ 写内核需要注意的一些事情 (原创)
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。