我在NASM中写了一个引导加载程序,它将64kb的程序数据从磁盘加载到从地址0060:0000[SEG:OFF]开始的内存中。我通过在程序集(NASM)中编写一些代码来测试我项目的这一部分,并将其放入磁盘中。工作正常!
整个项目对于完全用Assembly编写来说有点复杂。因此,我决定将C与内联程序集一起使用,以便进一步使用。为此,我下载了一个名为open-watcom-c-win32-1.9的环境。我有一个简单的c代码,用于测试一些watcom编译器和链接器指令,以生成RAW BIN文件。bin文件是在我的引导加载程序将其加载到内存后生成的,但不会运行。我尝试了很多wlink指令来设置段和偏移值,但都不起作用。
void main()
{
__asm
{
mov ah, 0x0E
mov al, '!'
int 0x10
}
}
我认为问题在于编译器和链接器在生成代码时使用了错误的段和偏移地址。因为Wlink在任何情况下都会丢弃以下错误。
警告!W1023未找到起始地址,使用0000:0000
我不知道如何正确设置段偏移地址,但这对于一个工作程序来说是必要的。我的问题是,我使用什么样的WatCom指令来从具有声明段:偏移量的C源代码生成16位真实模式RAW BIN文件?这有可能与WatCom或我需要使用其他东西?
由于C函数的顺序有些不可预测,因此在实际入口点需要一些特殊的init代码。在这种情况下,入口点总是在文件的最开始。这个初始代码的编码偏移量还规定了所有其他地址的偏移量(segemnt无关紧要,编译器对此没有任何假设)。您可能想要编写自己非常精简的init代码。默认的init代码在cstart_t.obj文件中,因此需要替换它。具体需要放什么取决于你需要什么,如果链接器抱怨缺少一些符号,你可能需要把它放在那里。像这样的一个最小的函数可以用于您的示例代码,但可能会使一些C函数无法使用(用Nasm语法编写):
global __STK
extern main_ ; The actual name of the main function depends on the memory model I think.
section _INIT class=CODE
resb 0 ; The expected offset of the code.
..start:
jmp main_ ; Don't expect main() to return.
section _STACK stack class=STACK
__STK:
group DGROUP _INIT _STACK