Home > Software engineering >  Extern C compiled fn in asm
Extern C compiled fn in asm

Time:12-12

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 $
  • Related