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

5.3k Views Asked by At

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?

2

There are 2 best solutions below

8
On BEST ANSWER

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

2
On

First of all, if you're compiling to ELF, then you mustn't add an initial underscore before functions in assembly.

Now, in order to link different source files together, you obviously have to get them to common ground, which is in this case, object code.

So, what you'll do is:

  1. Assemble the assembly source files to object code.
  2. Compile but not link C source files to object code. In gcc: gcc -c file.c -o file.o
  3. Link those together. In gcc: gcc cfile.o asfile.o -o app