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

GAS汇编开发bootloader时自定义print函数无输出问题排查

问题排查与修复方案

核心错误点

1. 字符串指针寄存器不匹配

你在main函数中将字符串地址存入了%ebx,但print函数中是从%rbp读取字符地址,根本没有访问目标字符串,自然无法输出预期内容。

2. BIOS中断参数被破坏

int $0x10的0x0e打印功能要求:

  • %ah固定为0x0e
  • %al存储待打印字符
  • %bh为显示页号(实模式下一般设为0)
  • %bl为字符颜色(文本模式下默认0x07为黑底白字)
    你将字符串地址存入%ebx,调用中断时%bh/%bl的值是地址的高低位,完全不符合中断参数要求,会导致输出失败。

3. 字符串无终止符

你用.ascii定义的字符串末尾没有添加0值,print函数是通过判断%al == 0终止打印的,会一直读取字符串后的随机内存内容,直到碰到随机0值才停止。

4. 编译链接参数错误

BIOS启动bootloader时处于16位实模式,默认as命令会生成32/64位代码,实模式下执行会出错;且bootloader会被BIOS加载到物理地址0x7c00,你链接时没有指定代码起始地址,所有符号(比如msg)的地址计算都是错误的。

5. 换行符不兼容

BIOS的0x0e打印功能不会自动处理\n为回车+换行,需要手动输出0x0d(回车)和0x0a(换行)才能实现正常换行。


修复方法

1. 修正编译链接命令

# 显式指定生成16位汇编代码
as --16 boot_main.s -o boot.o
# 链接时指定代码起始地址为0x7c00,和BIOS加载位置一致
ld -o boot.bin --oformat binary -e main -Ttext 0x7c00 boot.o

2. 修正代码

boot_print.s

print:
        movb    (%bx), %al
        cmpb    $0, %al
        je      print_end
        # 每次调用中断前重置参数,避免寄存器值干扰
        movb    $0x0e, %ah
        movw    $0x0007, %bx
        int     $0x10
        inc     %bx
        jmp     print
print_end:
        ret

boot_main.s

.code16 # 显式指定生成16位代码
.global main

main:
        # 初始化段寄存器,消除BIOS残留值影响
        xor %ax, %ax
        mov %ax, %ds
        mov %ax, %es

        movw    $msg, %bx
        call    print
        jmp .

.include "boot_print.s"

msg:
        .ascii  "Hello, World!"
        .byte 0x0d, 0x0a # 显式添加回车换行
        .byte 0 # 添加字符串终止符

.fill   510-(.-main), 1, 0
.word   0xaa55

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 23:15:02