2. 编写并运行Hello World引导扇区

任务目标

编写一个可直接引导的Hello World引导扇区程序,将其写入虚拟软盘镜像的首扇区,并通过QEMU验证启动后屏幕显示字符串。

环境依赖

  • NASM汇编器(nasm)
  • QEMU模拟器(qemu-system-x86_64)
  • Linux/macOS终端环境

实现原理

BIOS在自检完成后,会将启动设备的第一个扇区(512字节)加载到内存地址0x7C00处,并跳转执行。引导扇区代码需以0x55AA作为结束标志(偏移510处为0x55,偏移511处为0xAA),BIOS才会将其识别为合法引导扇区。本案例使用BIOS中断int 0x10的0x0E功能(TTY字符输出)逐字符打印字符串,最后通过cli; hlt停机。

完整代码

; hello_boot.asm
[org 0x7C00]          ; 告诉汇编器代码将被加载到0x7C00

mov si, msg           ; SI指向要打印的字符串
call print_string      ; 调用打印函数

cli                   ; 关闭中断
hlt                   ; 停机

print_string:
    lodsb             ; 加载SI指向的字符到AL,SI自增
    or al, al         ; 检查AL是否为0(字符串结束符)
    jz .done          ; 若为0则返回
    mov ah, 0x0E      ; BIOS TTY输出功能号
    int 0x10          ; 调用BIOS视频中断
    jmp print_string  ; 继续下一个字符
.done:
    ret

msg db 'Hello, World!', 0

times 510-($-$$) db 0 ; 填充至510字节
dw 0xAA55             ; 引导扇区结束标志(小端序写入)

编译与运行

# 1. 编译为二进制文件
nasm -f bin hello_boot.asm -o hello_boot.bin

# 2. 创建1.44MB软盘镜像(大小任意,QEMU可识别)
dd if=/dev/zero of=boot.img bs=512 count=2880

# 3. 将引导扇区写入镜像起始位置
dd if=hello_boot.bin of=boot.img bs=512 count=1 conv=notrunc

# 4. 用QEMU启动
qemu-system-x86_64 -drive format=raw,file=boot.img

验证方法

QEMU窗口启动后,屏幕左上角应显示Hello, World!字符串,且系统不再继续执行(无引导错误提示)。若使用echo $?检查QEMU退出码,手动关闭窗口时返回码非0属正常现象。

常见问题

  • 屏幕无输出:确认nasm编译无报错,且dd写入时使用了conv=notrunc(防止截断镜像)。
  • 提示“Boot failed”:检查二进制文件最后两个字节是否为55 AA,可用xxd hello_boot.bin | tail -1查看。
  • 字符串乱码:确认代码中[org 0x7C00]未被删除,否则内存引用地址会偏移。