繁体   English   中英

实模式OS中的16位.com C程序

[英]16-bit .com C program in real mode OS

我一直在研究一个真正的模式操作系统,用汇编编写并使用NASM编译成扁平的.bin可执行文件。
我想用C编写一些操作系统,所以写了一个实验程序(ctest.c),我想访问一个字符串并打印第一个字符:

void test();

int main() { test(); return 0; }

char msg [] = "Hello World!";

void test() {
    _asm
    {
        mov si, word ptr [msg]
        mov al, [si]
        mov ah, 0eh
        int 10h
    }
    for(;;);
}

我使用wcl ctest.c -lr -l=COM在Open Watcom v1.9中编译了这个。 这创建了ctest.com。 我在NASM程序集中编写的内核将此程序加载到0x2010:0x0000,将DS和ES设置为0x2000:0x0000,然后跳转到0x2010:0x0000。 这就是我一直在调用汇编编写的.COM程序,并使用nasm -f bin test.asm -o test.com编译。
当我测试操作系统(使用Bochs)时,它成功加载ctest.com,但打印出一个无意义的字符,该字符不属于msg []。
有人对此有任何建议吗? 我认为字符串只是在错误的地方初始化。 我想将其保留为16位操作系统。
谢谢!

您使用的是错误的地址。

你要么加载到0x2000:0x0100并跳转到0x2000:0x0100(不要忘记在此之前设置DS = ES = SS = 0x2000和SP = 0) 或者你加载到0x2000:0x0000(相当于0x1FF0:0x0100因为0x2000 * 0x10 + 0x0000 = 0x1FF0 * 0x10 + 0x0100 = 0x20000 =实模式下的物理存储器地址)并跳转到0x1FF0:0x0100(不要忘记在此之前设置DS = ES = SS = 0x1FF0和SP = 0)。

所有这一切的原因是编译的x86代码通常不是位置独立的,如果你移动它,你必须调整代码内部的一些数据偏移。 显然,你没有做出这些调整。 在简单的情况下,没有什么可以调整,你得到了错误的地址。

编辑

实际上,这里有更多的问题:

  1. mov si, word ptr [msg]必须更改为lea si, byte ptr [msg]因为你不想用字符串里面的内容加载si ,你想用字符串的地址加载它。
  2. 由OW链接到您的程序的启动代码依赖于DOS并调用DOS函数,这是您在启动程序时没有的。 看看如何解决这个问题

在MS-DOS下,COM程序在偏移0x100处加载。 我猜想Open Watcom会做出这样的假设。 我建议加载COM程序在0x2010:0x0100,看看它做了什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM