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

Bootloader输出乱码问题求助:次级引导程序显示异常字符

次级Bootloader打印乱码问题排查与修复

核心问题分析

从你提供的代码和现象来看,数据段寄存器(DS)设置时机错误是导致乱码的主要原因:

  1. 代码开头先调用print打印启动信息,但此时DS寄存器尚未初始化,默认值指向错误内存区域,读取starting_message时会读到RAM中的垃圾数据,引发乱码。
  2. 你设置ds = 0x07C0,但次级引导程序的ORG是0x8000,正确的DS配置应为0x0000(0x0000:0x8000才是次级引导程序加载的物理地址0x8000),错误的段地址会导致所有数据访问偏移出错,进一步触发内存读取异常。

修复步骤

1. 优先初始化数据段寄存器

在调用print函数前,先正确设置DS和ES,确保数据访问地址匹配程序加载位置:

start:
    mov ah, 0x00
    mov al, 0x03
    int 0x10

    ; 初始化DS/ES为0x0000,匹配ORG 0x8000的加载地址
    xor ax, ax
    mov ds, ax
    mov es, ax

    mov si, starting_message
    call print

2. 修正磁盘读取的段地址

后续调用int 0x13读取分区表时,bx = buffer的地址依赖DS,保持DS为0x0000即可,无需改成0x07C0(该值对应MBR的段地址)。

3. 优化换行符显示(可选)

启动信息结尾的0x0A(换行)无法被BIOS中断int 0x10的0x0E功能自动处理,可修改print函数手动调整光标位置:

print_loop:
    mov al, [si] 
    cmp al, 0 
    je print_done 

    cmp al, 0x0A
    je handle_newline

    mov ah, 0x0E 
    int 0x10 
    inc si 
    jmp print_loop

handle_newline:
    ; 获取当前光标位置
    mov ah, 0x03
    xor bh, bh
    int 0x10
    ; 光标移至下一行开头
    mov ah, 0x02
    inc dh
    mov dl, 0
    int 0x10
    inc si
    jmp print_loop

4. 主动清零关键数据区(可选)

为避免内存残留数据干扰,可在启动时主动清零buffer、pit_info等变量:

; 初始化DS后执行
mov cx, 16
mov di, buffer
xor ax, ax
rep stosb

mov di, pit_info
rep stosb

额外验证点

  • 确认次级引导程序加载地址:在QEMU中用info registers查看CS:IP,或用x/100i 0x8000断点调试代码位置。
  • 检查磁盘读取状态:确认int 0x13读取分区表未失败,避免错误处理分支因DS错误导致异常输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:27:51