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
编译与运行
- 保存上述代码为
int10_str.asm - 编译:
nasm -f bin int10_str.asm -o int10_str.bin - 运行(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结束程序。