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

用NASM编写Bootloader时int 0x10能显示单个字符却无法显示字符串是什么原因?

问题根因排查

核心错误:段寄存器赋值逻辑错误

你代码开头用mov ax, cs后赋值给ds、es的逻辑不可靠:

  • x86 BIOS跳转到引导扇区执行时,没有统一规范cs的取值,部分BIOS会用0x07c0:0x0000的段偏移组合跳转到0x7c00物理地址,此时cs值为0x07c0
  • 你用了org 0x7c00,所以代码里的BootMessage标签的偏移值是相对于0x7c00物理地址计算的,也就是当段地址为0时,BootMessage的偏移刚好是对应物理地址的正确值
  • 你把es设为非0的cs值后,es:bp指向的实际物理地址会变成cs*16 + BootMessage,和字符串实际存储的物理地址偏移了cs*16字节,自然读不到正确的字符串,也就无法显示内容
  • 你测试用的ah=0xe输出字符的BIOS功能不需要依赖es段寄存器,所以不受段地址错误的影响,能正常显示字符,和你的测试现象完全吻合。

次要潜在风险:栈未初始化

部分BIOS的int 0x10中断会用到栈,你没有初始化ss和sp寄存器,可能出现栈覆盖代码数据的异常。

修复方案

替换你代码开头的段寄存器赋值逻辑即可:

org 0x7c00
; 手动把所有段寄存器设为0,匹配org 0x7c00的地址约定
xor ax, ax
mov ds, ax
mov es, ax
; 初始化栈到0x7c00向下增长,不会覆盖引导扇区内容
mov ss, ax
mov sp, 0x7c00

call dispStr
jmp $

dispStr:
    mov ax, 0x0003
    int 0x10
    mov ax, BootMessage
    mov bp, ax
    mov cx, 16
    mov ax, 0x1301
    mov bx, 0x001f
    mov dl, 0x0000
    int 0x10
    ret

BootMessage db "Hello, OS world!"

times 510 - ($ - $$) db 0
dw 0xaa55

修改后重新编译写入虚拟磁盘即可得到预期效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:18:04