I'm following an OS dev series by poncho on yt.
The 6th video linked C with assembly code using extern
but the code was linked as C
code as it was extern "C" void _start()
.
In ExtendedProgram.asm
, _start
was called like:
[extern _start]
Start64bit:
mov edi, 0xb8000
mov rax, 0x1f201f201f201f20
mov ecx, 500
rep stosq
call _start
jmp $
The Kernel.cpp
had:
extern "C" void _start() {
return;
}
One of the comments in the video shows that for C
a different name, _Z6_startv
is
created.
So to try out I modified my Kernel.cpp
as:
extern void _Z6_startv() { return; }
And also modified the ExtendedProgram.asm
by replacing _start
with _Z6_startv
but the linker complained,
/usr/local/x86_64elfgcc/bin/x86_64-elf-ld: warning: cannot find entry symbol _start; defaulting to 0000000000008000
then I tried, Kernel.cpp
extern "C " void _Z6_startv() { return; } // I didn't even know wut i was doin'
And linker complained again.
I did try some other combinations & methods, all ending miserably, eventually landing here on Stack Overflow.
So, the question:
How to compile the function as a C
function and link it to assembly?
CodePudding user response:
there is a confusion between symbols:
The name of your function start
will be mangled to _Z6_startv
at compilation which means that the symbols that the linker (and your asm code) can use is _Z6_startv
. mangling is what c compilers normaly do, but extern "C"
tell the compiler to treat the function as if declared for a C program where no mangling happen so _start
stay _start
which means you do not need to change anything from the code you initialy showed.
or if you want to remove the extern "C"
what you want to do is:
[extern _Z6_startv]
Start64bit:
mov edi, 0xb8000
mov rax, 0x1f201f201f201f20
mov ecx, 500
rep stosq
call _Z6_startv
jmp $