cassemblyx86nasmtdm-gcc

How to compile and link C and ASM together on Windows for my OS


I have a problem with my 32-bit protected mode OS project Sinatra. I can compile sources to object files, but I don't know how to link these together. I use NASM and TDM-GCC on Windows. I have fixed problems with my code so it compiles. I have removed the comments for brevity.

My file boot.asm:

[BITS 32]
[global start]
[extern _JlMain]
start: 
    cli
    call _JlMain
    hlt

My file JSinatra.h:

#ifndef __SINATRA_H__
#define __SINATRA_H__

#define JWhiteText 0x07
void JlMain();
void JlClearScreen();
unsigned int JlPrintF(char * message, unsigned int line);

#endif

My file JSinatra.c:

#include "JSinatra.h"

void JlClearScreen() // clear entire screen
{
    char * vidmem = (char * ) 0xb8000;
    unsigned int i = 0;
    while (i < (80 * 25 * 2)) {
        vidmem[i] = ' ';
        i += 1;
        vidmem[i] = JWhiteText;
        i += 1;
    }
}
unsigned int JlPrintF(char * message, unsigned int line) {
    char * vidmem = (char * ) 0xb8000;
    unsigned int i = 0;
    i = line * 80 * 2;
    while ( * message != 0) {
        if ( * message == '\n') {
            line += 1;
            i = (line * 80 * 2); * message += 1;
        } else {
            vidmem[i] = * message; * message += 1;
            i += 1;
            vidmem[i] = JWhiteText;
            i += 1;
        }
    }
    return (1);
}
void JlMain() {
    JlClearScreen();
    JlPrintF("Sinatra v0 Virgin/Kernel Mode\n", 0);
}

I need to load my OS starting at absolute address 0x100000. How can I properly compile and link my code to create a binary image?


Solution

  • Using GCC-TDM and NASM on Windows

    Because you are targeting an OS being loaded at an absolute address without C-runtimes you'll need to make sure you compile as freestanding code; that your asm and C files target the same type of object (win32/PECOFF); and the last step will be converting the PECOFF file to a binary image.

    To compile C files you would use something like:

    gcc -m32 -ffreestanding -c JSinatra.c -o JSinatra.o
    

    To assemble the asm files you would use something like:

    nasm -f win32 boot.asm -o boot.o
    

    To link them together you have to do it in two steps:

    ld -m i386pe -T NUL -o sinatra.tmp -Ttext 0x100000 boot.o JSinatra.o
    

    The ld command above will create a temporary file sinatra.tmp that is a 32-bit PECOFF executable. You then need to convert sinatra.tmp to a binary image with a command like:

    objcopy -O binary sinatra.tmp sinatra.img
    

    You should then have a binary image in the file sinatra.img