Help in creating a 16-bit OS

I am trying to build an old DOS-like 16-bit OS.

My example kernel code:

    asm(".code16\n");
    void putchar(char);
    int main()
    {
    putchar('A');
    return 0;
    }
    void putchar(char val)
    {
       asm("movb %0, %%al\n"  
           "movb $0x0E, %%ah\n" 
           "int $0x10\n"
          :
          :"r"(val)
          ) ;
    }

      

This is how I compile it:

nasm -f bin -o ./bin/boot.bin ./source/boot.asm
gcc -nostdinc -fno-builtin -I./include -c -o ./bin/kernel.o ./source/kernel.c
ld -Ttext=0x9000 -o ./bin/kernel.bin ./bin/kernel.o -e 0x0
dd if=/dev/zero of=./bin/empty.bin bs=1440K count=1
cat ./bin/boot.bin ./bin/kernel.bin ./bin/empty.bin|head -c 1440K > ./bin/os
rm ./bin/empty.bin

      

and I run it in a virtual machine.

When I do putchar function (in kernel code) for constant value .... for example:

 void putchar()
 {
    char val = 'A';
    asm("movb %0, %%al\n" 
    "movb $0x0E, %%ah\n" 
    "int $0x10\n"
    :
    :"r"(val)
    ) ;
 }

      

then it works fine. But when I pass an argument to it (this is in the previous code), it prints a space for any character. What should I do?

+2


a source to share


2 answers


If you are trying to generate gcc 16-bit code, you need to use .code16gcc

, not .code16

to properly manipulate the stack for function parameters: see "Writing 16-bit code" in the gas documentation .



(Also, depending on which version of gcc you are using, you may need to compile yours kernel.c

with a parameter -fno-unit-at-a-time

or -fno-toplevel-reorder

to make sure the directive asm()

actually occurs in assembler before any compiled code - otherwise the compiler might mess things up.)

+3


a source


I find another compiler to solve the problem: bcc



It is a C compiler for the 8086 cpus, which is essential for developing bootloaders or BIOS related 8086 code.

+1


a source







All Articles