1

我在 NASM 中编写了一个引导加载程序,它将 64kb 的程序数据从磁盘加载到从地址 0060:0000 [SEG:OFF] 开始的内存中。我通过在汇编中编写一些代码(NASM)测试了我项目的这一部分并将其放入磁盘中。工作正常!

完整的项目完全用汇编编写有点复杂。所以我决定进一步使用 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 有可能还是我需要使用其他东西?

4

1 回答 1

1

由于 C 函数的顺序有些不可预测,因此在实际入口点需要一些特殊的初始化代码。在这种情况下,入口点始终位于文件的开头。此初始代码的编码偏移量还指示所有其他地址的偏移量(段无关紧要,编译器对此不做任何假设)。您可能想要编写自己的非常精简的初始化代码。默认初始化代码在文件 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
于 2015-08-03T02:35:13.610 回答