关于90H号中断TSR服务程序执行输出的技术咨询
90H中断TSR触发异常输出的问题解析
首先直接给结论:触发程序执行后会输出hello,核心原因是你提供的TSR服务程序根本没有完成中断向量表替换和内存驻留的关键步骤,导致int 90H调用的还是系统默认处理逻辑,再结合触发程序自身的上下文,最终输出了它自己数据段的字符串。
1. TSR程序的致命缺陷:缺失初始化核心代码
你给出的TSR代码只有跳转指令、输出字符串和中断服务程序(ISR),但完全没有实现TSR最关键的initialize初始化逻辑。一个正常的TSR必须完成这几步核心操作:
- 调用DOS中断
int 21h ah=35h获取原90H号中断的向量地址并保存,用于后续链式调用或恢复; - 调用DOS中断
int 21h ah=25h将自己的isra90服务程序地址写入90H号中断向量表; - 调用DOS中断
int 21h ah=31h将程序驻留内存,而不是直接退出。
现在你的TSR只有jmp initialize的跳转指令,但没有initialize标签对应的代码,程序运行后要么直接崩溃退出,要么执行无效代码,完全没修改中断向量表,所以90H号中断还是系统默认的处理程序,根本不会调用你写的isra90。
2. 触发程序输出hello的原因
触发程序的数据段定义了msg db "hello $",代码段执行int 90H。结合DOS系统的默认行为和程序上下文来看:
- DOS系统中,默认的
int 90H是一个空闲循环中断,通常用于短暂延时,但如果触发程序在执行int 90H之前,恰好把DX寄存器指向了自身数据段的msg(你可能省略了这部分代码),而默认的int 90H处理逻辑又刚好触发了DOS的字符串输出功能(ah=09h int 21h),就会意外输出hello; - 另一种可能是内存布局或寄存器状态的巧合,导致
int 90H执行时误触发了输出操作。
3. 如何让TSR正常工作
要让int 90H触发TSR的预期输出,你需要补充TSR的初始化代码,示例如下:
jmp initialize msg db "this is 2 times", 0ah ,0dh, '$' old90 dd ? ; 用于保存原90H中断向量 isra90 proc push ax push dx lea dx, cs:msg mov ah, 09h int 21h inc byte ptr msg+8 ; 每次执行数字递增,比如从2变成3、4... pop dx pop ax jmp cs:old90 ; 链式调用原中断(可选,根据需求决定) iret isra90 endp initialize: ; 获取原90H中断向量 mov ah, 35h mov al, 90h int 21h mov word ptr old90, bx mov word ptr old90+2, es ; 设置新的90H中断向量 mov ah, 25h mov al, 90h lea dx, isra90 int 21h ; 驻留内存,DX是驻留的字节数(取initialize之前的偏移) mov ah, 31h mov al, 0h ; 退出码0 mov dx, offset initialize int 21h
补充这段代码后,运行TSR程序,它会驻留内存并替换90H中断向量,此时再运行触发程序,执行int 90H就会输出TSR里的this is 2 times,而且每次执行数字会递增。
内容的提问来源于stack exchange,提问作者Mostfa shma
相关产品推荐
相关产品推荐

