[英]16-bit .com C program in real mode OS
I've been working on a real mode OS, writing in assembly and compiling to flat .bin executables with NASM. 我一直在研究一个真正的模式操作系统,用汇编编写并使用NASM编译成扁平的.bin可执行文件。
I would like to write some of the OS in C, and so wrote an experiment program (ctest.c) which I would like to access a string and print the first character: 我想用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(;;);
}
I compiled this with Open Watcom v1.9 using wcl ctest.c -lr -l=COM
. 我使用
wcl ctest.c -lr -l=COM
在Open Watcom v1.9中编译了这个。 This creates ctest.com. 这创建了ctest.com。 The kernel, which I wrote in NASM assembly, loads this program to 0x2010:0x0000, sets DS and ES to 0x2000:0x0000 and then jumps to 0x2010:0x0000.
我在NASM程序集中编写的内核将此程序加载到0x2010:0x0000,将DS和ES设置为0x2000:0x0000,然后跳转到0x2010:0x0000。 This is how I have been calling .COM programs written in assembly and compiled with
nasm -f bin test.asm -o test.com
. 这就是我一直在调用汇编编写的.COM程序,并使用
nasm -f bin test.asm -o test.com
编译。
When I test the OS (using Bochs), it successfully loads ctest.com, but prints out a meaningless character that is not part of msg[]. 当我测试操作系统(使用Bochs)时,它成功加载ctest.com,但打印出一个无意义的字符,该字符不属于msg []。
Does anyone have any suggestions about this? 有人对此有任何建议吗? I think the string is just being initialized in the wrong place.
我认为字符串只是在错误的地方初始化。 I would like to keep this as a 16-bit OS.
我想将其保留为16位操作系统。
thanks! 谢谢!
You are using wrong addresses. 您使用的是错误的地址。
You either load at 0x2000:0x0100 and jump to 0x2000:0x0100 (don't forget setting DS=ES=SS=0x2000 and SP=0 prior to that) OR you load at 0x2000:0x0000 (equivalent to 0x1FF0:0x0100 because 0x2000*0x10+0x0000 = 0x1FF0*0x10+0x0100 = 0x20000 = physical memory address in real mode) and jump to 0x1FF0:0x0100 (don't forget setting DS=ES=SS=0x1FF0 and SP=0 prior to that). 你要么加载到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)。
The reason for all of this is that compiled x86 code is generally not position-independent and if you move it, you have to adjust some data offsets inside of the code. 所有这一切的原因是编译的x86代码通常不是位置独立的,如果你移动它,你必须调整代码内部的一些数据偏移。 Obviously, you weren't making these adjustments.
显然,你没有做出这些调整。 In simple cases there was nothing to adjust and you got away with wrong addresses.
在简单的情况下,没有什么可以调整,你得到了错误的地址。
EDIT : 编辑 :
Actually, there're more problems here: 实际上,这里有更多的问题:
mov si, word ptr [msg]
must change to lea si, byte ptr [msg]
because you don't want to load si
with what's inside the string, you want to load it with the string's address. mov si, word ptr [msg]
必须更改为lea si, byte ptr [msg]
因为你不想用字符串里面的内容加载si
,你想用字符串的地址加载它。 Under MS-DOS, COM programs were loaded at offset 0x100. 在MS-DOS下,COM程序在偏移0x100处加载。 I would guess that Open Watcom makes that assumption.
我猜想Open Watcom会做出这样的假设。 I would suggest loading the COM program at 0x2010:0x0100 and see what that does.
我建议加载COM程序在0x2010:0x0100,看看它做了什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.