3. 实现BIOS中断调用显示字符串

任务目标

在实模式(Real Mode)下,通过BIOS中断 INT 10h 的功能号 13h(写字符串)或 0Eh(TTY模式逐字符输出),将一段字符串显示到屏幕。本案例使用NASM汇编语言编写,通过 INT 10h 中断调用实现字符串显示,并提供一个可直接编译运行的最小示例。

环境与依赖

  • NASM(Netwide Assembler)—— 汇编编译器
  • QEMU(可选,用于在虚拟机中测试引导扇区)或DOS环境(如FreeDOS)
  • 目标平台:x86实模式(16位)

核心实现

以下代码实现两种显示方式:0Eh 逐字符TTY输出(适用于任何显示模式),以及 13h 一次性写入字符串(适用于文本模式)。代码编译为引导扇区,可直接用QEMU启动验证。

;--------------------------------------------------------
; BIOS中断调用显示字符串 —— 引导扇区示例
; 编译: nasm -f bin int10_str.asm -o int10_str.bin
; 运行: qemu-system-x86_64 -fda int10_str.bin
;--------------------------------------------------------
[org 0x7c00]
[bits 16]

start:
    ; 清屏 (功能号 00h, 设置显示模式为 80x25 彩色文本)
    mov ax, 0x0003
    int 0x10

    ; 方法1: 使用 INT 10h / AH=0Eh (TTY逐字符输出)
    mov si, msg_tty
    call print_tty

    ; 方法2: 使用 INT 10h / AH=13h (写字符串, 需要ES:BP指向字符串)
    mov ax, 0x1301          ; AH=13h, AL=01h (光标跟随移动)
    mov bx, 0x0007          ; BH=页码(0), BL=属性(07h=白字黑底)
    mov cx, msg_str_len     ; 字符串长度
    mov bp, msg_str         ; ES:BP = 字符串地址
    push cs
    pop es                  ; ES = CS
    mov dx, 0x0100          ; DH=行(1), DL=列(0)
    int 0x10

    ; 暂停等待按键
    mov ah, 0x00
    int 0x16

    ; 重启
    mov ax, 0x0040
    mov ds, ax
    mov word [0x0072], 0x0000  ; 设置复位标志
    jmp 0xffff:0x0000

;--------------------------------------------------------
; print_tty: 使用 INT 10h / AH=0Eh 逐字符输出
; 输入: SI = 以0结尾的字符串地址
;--------------------------------------------------------
print_tty:
    mov ah, 0x0e
.loop:
    lodsb                   ; AL = [SI], SI++
    test al, al
    jz .done
    int 0x10                ; 输出字符
    jmp .loop
.done:
    ret

;--------------------------------------------------------
; 数据段
;--------------------------------------------------------
msg_tty    db 'TTY mode: Hello BIOS!', 0x0d, 0x0a, 0
msg_str    db 'String mode: INT 10h/13h works!'
msg_str_len equ $ - msg_str

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

编译与运行

  1. 保存上述代码为 int10_str.asm
  2. 编译:nasm -f bin int10_str.asm -o int10_str.bin
  3. 运行(QEMU):qemu-system-x86_64 -fda int10_str.bin

验证方法

启动后屏幕应显示两行内容:

  • 第一行(第0行):TTY mode: Hello BIOS! —— 由 0Eh 功能逐字符输出
  • 第二行(第1行):String mode: INT 10h/13h works! —— 由 13h 功能一次性写入

若两行均正确显示且无乱码,说明BIOS中断调用成功。按任意键后系统重启,可作为功能正常的附加验证。

关键说明

  • INT 10h / AH=0Eh 是TTY模式输出,自动处理换行(0x0d回车、0x0a换行),适用于所有显示模式。
  • INT 10h / AH=13h 需要 AL 指定写入模式(01h 表示光标跟随移动),ES:BP 指向字符串,CX 为字符串长度,DX 为起始行列。
  • 引导扇区最后两字节必须为 0xAA55,BIOS才能识别并加载。
  • 若在DOS/Windows下测试,可将代码中的引导扇区部分移除,仅保留 start 标签后的逻辑,并使用 int 20h 结束程序。