开发类MS-DOS控制台汇编OS:实现按键捕获与打印功能
实现SMOS Shell的按键捕获与打印功能
嘿,很高兴看到你在折腾自己的类MS-DOS控制台系统SMOS!虽然这类底层项目维护起来确实要费不少劲,但这种从零构建系统的乐趣绝对值得,给你点个赞👍
先贴出你目前的SMOS Shell源码(已按格式整理):
;------------------------------------------------------ ;| SMOS Shell Source | ;| Kept under GPLv3 Open Source license | ;------------------------------------------------------ BITS 16 start: mov ax, 07C0h add ax, 288 ; 计算数据段地址 (07C0h * 16 + 512) mov ds, ax mov es, ax mov ss, ax mov sp, 0xffff ; 设置栈顶
接下来咱们来实现按键捕获并打印的核心功能。在16位实模式下,我们主要依赖BIOS中断来完成键盘输入和屏幕输出,下面是具体的实现方案:
核心实现逻辑
- 捕获按键:使用BIOS中断
int 16h的0号功能,它会等待用户按下按键,返回的al寄存器存储按键的ASCII码,ah存储扫描码 - 打印字符:使用BIOS中断
int 10h的0Eh功能,将al中的ASCII字符输出到屏幕,同时光标会自动向后移动 - 循环处理:用无限循环持续监听键盘输入,直到用户按下指定退出键(比如ESC)
修改后的完整可运行源码
;------------------------------------------------------ ;| SMOS Shell Source | ;| Kept under GPLv3 Open Source license | ;------------------------------------------------------ BITS 16 start: mov ax, 07C0h add ax, 288 ; 计算数据段地址 (07C0h * 16 + 512) mov ds, ax mov es, ax mov ss, ax mov sp, 0xffff ; 设置栈顶 ; 初始化屏幕为80x25彩色文本模式 mov ah, 00h mov al, 03h int 10h ; 打印欢迎信息 mov si, welcome_msg call print_string ; 按键捕获与打印循环 keyboard_loop: mov ah, 00h ; int 16h功能0:等待按键输入 int 16h ; 检查是否按下ESC键(扫描码为01h),按下则退出循环 cmp ah, 01h je exit_loop mov ah, 0Eh ; int 10h功能0E:打印字符 int 10h jmp keyboard_loop ; 回到循环继续监听 exit_loop: hlt ; 暂停CPU ; 字符串打印函数 print_string: mov ah, 0Eh .print_char: lodsb ; 从si指向的内存读取一个字节到al,si自增 cmp al, 0 ; 判断是否到字符串结束 je .done int 10h jmp .print_char .done: ret ; 数据段 welcome_msg db 'SMOS Shell - Press any key to type, ESC to exit.', 0Dh, 0Ah, 0 ; 引导扇区结束标记 times 510-($-$$) db 0 dw 0xAA55
关键代码解释
keyboard_loop循环:这是核心的输入处理循环,不断调用int 16h等待按键输入- ESC键退出判断:通过对比
ah寄存器的扫描码(ESC的扫描码是01h),实现循环退出逻辑 print_string函数:通用的字符串打印工具,通过lodsb逐个读取字符并调用int 10h输出- 引导扇区标记:最后加上
times 510-($-$$) db 0和dw 0xAA55,让这段代码能被BIOS识别为合法的引导扇区
你可以把这段代码用NASM编译成二进制文件,然后用虚拟机或者模拟器运行,就能看到按键输入并实时打印的效果了!
内容的提问来源于stack exchange,提问作者user5380448
相关产品推荐
相关产品推荐

