0

I'm trying to make a super simple c++ and assembly project in Visual Studio, but when trying to call a function defined in main.cpp from boot.asm, I get an error: unresolved external symbol kernel_main

I've already declared the function with extern "C" and changed the item type of boot.asm to Microsoft Macro Assembler but the problem still persists.

boot.asm:

.code
org        07c00h
main:
        jmp short start
        ret

start:
        cli
        mov ax,cs
        mov ds,ax
        mov es,ax
        mov ss,ax
        mov bp,7c00h
        mov sp,7c00h
        sti

        extern         kernel_main : PROC
        call           kernel_main
        ret

END

main.cpp:

#include "main.h"

using namespace miniOS;

extern "C" int kernel_main()
{
    MiniOS::init();
    MiniOS::run();
    MiniOS::close();

    return 0;
}

main.h

#pragma once

#include "MiniOS.h"

extern "C" int kernel_main();
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Ryan Moore
  • 11
  • 2
  • 1
    Try adding a leading underscore in your asm file only, e.g. `_kernel_main`. – Jester Aug 17 '22 at 22:56
  • 2
    Probably because it was named `_kernel_main` (Win32 convention). What you are doing won't work as you expected. Legacy BIOS boots in 16-bit mode. You'd have to switch into 32-bit mode (assuming you are compiling 32-bit code) and somehow the generating binary would have to be free of any Windows code. – Michael Petch Aug 17 '22 at 22:56
  • Adding an underscore in the asm file still gives me an error... I realise this probably won't run even if compiled, yes. I spent ages looking for a 16 bit compiler and linker and I decided I'd just work on this a bit before banging my head against the wall looking for those again. I'm quite new to assembly and I've never had to deal with any compilers besides Visual Studio and gcc. – Ryan Moore Aug 17 '22 at 23:10
  • Do you see VS trying to link your `main.obj`? – Jester Aug 17 '22 at 23:25
  • I don't see any evidence of it, no. – Ryan Moore Aug 17 '22 at 23:46
  • 1
    Right mouse click the ASM file and select properties. In there you should set the Item Type to Microsoft MASM assembler. To get that as the default for all ASM files you add to the project you'd right mouse click the project; select "build dependencies"; select "build customizations" and then put a check next to "masm" targets. This of course doesn't solve your 16-bit problem. The 32-bit linker (ML.EXE) in Visual Studio can generate 16-bit objects but the linker in VS doesn't support 16-bit. There is a linker16.exe in the MASM32 SDK https://masm32.com that you can copy to your path. – Michael Petch Aug 18 '22 at 00:41
  • The 16-bit linker isn't supported directly in Visual Studio so to link you'd have to create a custom linker setup to handle that (using link16.exe instead of the default one) – Michael Petch Aug 18 '22 at 00:42
  • Oh, thank you tons for the linker. Unfortunately though I've already tried changing the build customizations to include masm, still the same issue. – Ryan Moore Aug 18 '22 at 10:36
  • Do any of these help at all? [OSDev Forum: 16-bit C/C++ compiler?](https://forum.osdev.org/viewtopic.php?f=13&t=19768); [Looking for 16-bit x86 compiler](https://stackoverflow.com/questions/227762/looking-for-16-bit-x86-compiler); [Is there a C compiler that targets the 8086?](https://stackoverflow.com/questions/4493035/is-there-a-c-compiler-that-targets-the-8086). The one that keeps coming up is [Open Watcom C/C++](https://github.com/open-watcom), so if you haven't tried that yet, I would recommend it. – Schol-R-LEA Aug 18 '22 at 19:20
  • Keep in mind that, as currently written, the compiled C++ code would have to fit into the 510 bytes available in the boot sector. While this is not impossible, it is unlikely that the compiler and linker could produce something that tiny. As a rule, you would have to write a boot loader in assembly, which would then load the kernel from disk separately. – Schol-R-LEA Aug 18 '22 at 19:31
  • Also, if I understand correctly, both Visual Studio and Macro Assembler have clauses in their licenses that forbid their use in developing for non-Microsoft operating systems. I won't tell if you won't, but just something to take note of. It is part of the reason why most OS dev is done using either NASM or GAS, and the binutils/GCC suites. To the Subject Matter Experts here, if I am mistaken in this point, please let me know. – Schol-R-LEA Aug 19 '22 at 16:03
  • Oh, and the boot sector has to have a two-byte signature (AA55 hex) as the last two bytes of the sector, or the BIOS won't boot it. Getting the linker to insert the code between the assembly code and the signature won't be easy. Finally, most newer PCs (circa 2019 and later) no longer support Legacy BIOS booting, which means that the type of boot sector you are writing won't run on them except in emulation. This doesn't mean you shouldn't pursue the legacy boot loader, just be aware that it is obsolete for newer hardware. – Schol-R-LEA Aug 19 '22 at 16:10

0 Answers0