我正在 yt 上關注 poncho 的 OS 開發系列。
第6 個視頻使用匯編代碼將 C 與匯編代碼extern相鏈接,但C代碼原樣鏈接為代碼extern "C" void _start()。
在ExtendedProgram.asm,_start被稱為:
[extern _start]
Start64bit:
mov edi, 0xb8000
mov rax, 0x1f201f201f201f20
mov ecx, 500
rep stosq
call _start
jmp $
的Kernel.cpp有:
extern "C" void _start() {
return;
}
視頻中的C 一條評論顯示,為不同的名稱_Z6_startv創建了。
所以為了嘗試,我修改了我Kernel.cpp的:
extern void _Z6_startv() { return; }
并且還修改了ExtendedProgram.asm替換_start為_Z6_startv但聯結器抱怨,
/usr/local/x86_64elfgcc/bin/x86_64-elf-ld:警告:找不到入口符號_start;默認為 0000000000008000
然后我試了一下,Kernel.cpp
extern "C " void _Z6_startv() { return; } // I didn't even know wut i was doin'
聯結器再次抱怨。
我確實嘗試了一些其他的組合和方法,但都以悲慘的結局收場,最終登陸 Stack Overflow。
所以,問題:
如何將函式編譯為C 函式并將其鏈接到程式集?
uj5u.com熱心網友回復:
符號之間存在混淆:
您的函式名稱start將_Z6_startv在編譯時被重整,這意味著聯結器(和您的匯編代碼)可以使用的符號是_Z6_startv. mangling 是 C 編譯器通常所做的,但extern "C"告訴編譯器將該函式視為為 C 程式宣告的函式,其中沒有發生 mangling,所以_start保持_start不變,這意味著您不需要更改最初顯示的代碼中的任何內容。
或者如果你想洗掉extern "C"
你想要做的是:
[extern _Z6_startv]
Start64bit:
mov edi, 0xb8000
mov rax, 0x1f201f201f201f20
mov ecx, 500
rep stosq
call _Z6_startv
jmp $
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/381526.html
上一篇:為什么在同一節中參考全域函式的函式只能在鏈接時求解,而區域函式將在編譯時求解?
下一篇:匯編為什么是“leaeax,[eax eax*const];shleax,eax,const;”根據gcc-O2,組合速度比“imuleax,eax,const”快?
