帮助构建一个16位操作系统

3
我试图构建一个类似于旧的16位DOS操作系统。
我的示例内核代码:
    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)
          ) ;
    }

这是我编译它的方式:
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

我在虚拟机中运行它。
当我在内核代码中为常量值编写putchar函数时,就像这样:
 void putchar()
 {
    char val = 'A';
    asm("movb %0, %%al\n" 
    "movb $0x0E, %%ah\n" 
    "int $0x10\n"
    :
    :"r"(val)
    ) ;
 }

然后它就能正常工作了。但是当我向它传递参数(即在先前的代码中)时,它会为任何字符打印一个空格。我该怎么办?

你是指“像DOS一样的16位操作系统”,还是“16位的类似DOS的操作系统”? - Marcelo Cantos
哎呀...我不应该用“dos”这个词。让它只是一个16位基本操作系统就好了。:-) - brainbarshan
我删除了引导程序代码,因为我认为它与此无关。 - Earlz
2个回答

4
如果你想让gcc生成16位代码,需要使用.code16gcc而不是.code16,以便正确处理函数参数的堆栈操作:请参见gas文档中的“编写16位代码”
(另外,根据你使用的gcc版本,你可能需要使用-fno-unit-at-a-time-fno-toplevel-reorder选项来编译kernel.c,以确保asm()指令在任何已编译代码之前被汇编程序遇到。否则,编译器可能会重新排列代码。)

谢谢。它起作用了。现在我的putchar函数正常工作了。 但是出现了一个新问题。数组和指针方面的东西不起作用。 例如:char *str =“Hello”; putchar(str [0])。这不起作用。你能否给我一些提示或相关链接? - brainbarshan
可能是段寄存器的设置存在问题,或者代码没有在您认为的地址上运行。调试此问题的最佳方法是在允许您逐步执行代码的环境中运行它。我听说Bochs及其提供的调试工具对这种情况非常好,尽管我自己没有尝试过。 - Matthew Slattery

1
我找到了另一个编译器来解决这个问题:bcc 这是一个针对8086 CPU的C编译器,对于开发引导加载程序或BIOS相关的8086代码非常重要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接