16位x86汇编OS中EXEC内核函数光标定位异常问题求助
排查16位x86汇编OS中清屏后光标定位失效问题
核心可能原因
- 清屏指令(0X7F)的实现修改了光标位置的硬件状态或内部维护的坐标变量,导致后续定位逻辑读取了错误的初始值
- 光标定位代码的行号计算错误(混淆了BIOS的0基/1基行号规则)
- 清屏与打印指令的光标处理逻辑存在寄存器冲突,定位代码依赖的寄存器被清屏操作篡改
- 清屏指令未正确完成硬件层面的光标重置,导致后续定位操作未生效
分步排查方案
1. 验证清屏后的初始光标位置
在0X7F指令执行完成后,立即调用BIOS的光标位置读取功能,确认硬件层面的光标坐标:
; 读取光标位置 mov ah, 03h mov bh, 0 ; 目标页号 int 10h ; DH=当前行号(0基), DL=当前列号 ; 临时打印DH的值(转ASCII输出),确认清屏后光标位置
如果读取到DH=2(对应第3行),说明清屏操作本身将光标定位到了此处,后续的定位代码可能未正确覆盖该值。
2. 检查光标定位代码的逻辑
确认打印指令中设置光标的代码是否遵循BIOS规则:BIOS INT 10H AH=02H的行号参数是0基索引,即第4行对应DH=3。如果代码中误写为DH=2,则会落在第3行;如果写为DH=4,实际会定位到第5行。
正确的光标定位代码示例:
; 设置光标到第4行第0列 mov ah, 02h mov bh, 0 ; 显示页号 mov dh, 3 ; 0基行号(对应第4行) mov dl, 0 ; 列号 int 10h
3. 审计清屏指令的实现
检查0X7F清屏指令的代码,确认是否存在以下问题:
- 使用
INT 10H AH=06H(窗口滚动)时,是否错误设置了窗口参数(比如将起始行设为2),导致滚动后光标落在非预期位置 - 清屏完成后是否手动修改了光标位置,比如误将
DH设为2 - 清屏操作是否篡改了后续定位代码依赖的寄存器(如BX、DH等)
标准清屏实现参考:
; 0X7F清屏处理 mov ah, 06h mov al, 0 ; 清除整个窗口(AL=0表示滚动0行,即清空) mov bh, 07h ; 黑底白字属性 mov ch, 0 ; 窗口左上角行 mov cl, 0 ; 窗口左上角列 mov dh, 24 ; 窗口右下角行(80x25模式) mov dl, 79 ; 窗口右下角列 int 10h ; 重置光标到屏幕左上角 mov ah, 02h mov bh, 0 mov dh, 0 mov dl, 0 int 10h
4. 单步调试追踪状态变化
使用Bochs调试器设置断点:
- 在0X7F指令执行前、执行后分别断点,查看寄存器(DH、DL)和光标位置的变化
- 在打印指令的光标定位代码处断点,检查
DH的值是否为预期的3(0基第4行),以及执行INT 10H后光标位置是否正确更新
额外注意点
- 确认EXEC函数在处理不同指令时,是否正确保存和恢复寄存器上下文,避免指令间的寄存器污染
- 检查是否存在内存中维护的光标坐标变量,清屏后是否未同步更新该变量,导致打印指令使用了旧的坐标值
内容的提问来源于stack exchange,提问作者Alessio Spinellino
相关产品推荐
相关产品推荐

