You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Open Watcom为286 CPU编译Bootloader遇问题求助

问题解决:Open Watcom 286 Bootloader 二进制过大与垃圾输出问题

问题根源分析

你遇到的两个核心问题:

  1. 二进制文件过大:Watcom汇编器的org 7c00h会让链接器认为代码需要从0x7c00地址开始,因此在二进制文件开头填充大量0字节到该地址,导致文件接近32KB。
  2. 垃圾输出:去掉org后,段寄存器ds=0,但C代码编译出的字符串指针是偏移地址(从0开始),实际字符串加载在物理地址0x7c00+偏移处,导致读取错误内存;同时_print函数的参数获取逻辑错误,直接弹出栈顶的返回地址当作参数,破坏了程序执行流程。

修复方案

1. 修正汇编代码(init.asm)

  • 移除org 7c00h,调整段寄存器设置,让ds指向0x07c0(对应物理地址0x7c00,即BIOS加载bootloader的位置),这样偏移地址直接对应实际物理位置。
  • 修复_print函数的参数获取逻辑,使用bp寄存器安全访问栈参数,避免破坏返回地址。
  • 添加bootloader必备的512字节填充与0x55aa签名。

修改后的init.asm:

.code INIT
extern kernelMain_ : proc

;export functions
PUBLIC initMain
PUBLIC _print

initMain:
; 初始化段寄存器,ds=0x07c0对应物理地址0x7c00(0x07c0*16=0x7c00)
mov ax, 07C0h
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0FFFFh ; 栈指针设为段末尾,向下增长,避免覆盖bootloader
mov bp, sp

jmp kernelMain_

;void __cdecl print(char* message, unsigned short length);
_print:
  push bp          ; 保存基址指针
  mov bp, sp       ; 用bp访问栈参数
  mov si, [bp+6]   ; 获取第一个参数message(__cdecl从右往左压栈,message在bp+6)
  mov cx, [bp+4]   ; 获取第二个参数length

printLoop:
  mov ah, 0Eh      ; BIOS TTY输出功能号
  mov bh, 0        ; 视频页0
  mov bl, 01h      ; 前景色(蓝色)
  lodsb            ; 从[si]读取字节到al,si自增1
  int 10h          ; 调用BIOS视频中断
  loop printLoop   ; cx减1,非0则循环

  pop bp           ; 恢复基址指针
  ret              ; 返回,__cdecl由调用者清理栈

; 填充到512字节,添加bootloader签名0x55aa
REPEAT 510 - ($ - INIT)
    DB 0
ENDM
DW 0AA55h

end

2. 保持C代码(test.c)不变

extern void __cdecl print(char* message, unsigned short length);

void kernelMain(void)
{
  print("this is a test", 14);
}

3. 构建命令不变

wasm -2 -ms init.asm
wcc -2 -d0 -wx -ms -s -zl test.c
wlink file init.obj file test.obj format raw bin name test.bin option NODEFAULTLIBS,verbose,start=initMain ORDER clname CODE segment INIT

效果说明

  • 生成的test.bin大小为512字节,符合bootloader要求,不再有多余的0填充。
  • 程序运行时,ds=0x07c0让C代码的字符串指针直接指向加载后的物理地址,_print函数正确读取参数与字符串,输出正常内容。

内容的提问来源于stack exchange,提问作者fredlllll

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:57:32