`MOV AX,4C00H INT 21H`与`INT 20H`终止程序有何区别
DOS下两种程序退出中断的差异与常用选型原因
硬使用要求差异(最易踩坑的核心区别)
INT 20H是DOS从CP/M系统继承的遗留终止调用,存在强制前置条件:调用时CS寄存器必须指向当前进程的程序段前缀(PSP)段基址。一旦不满足这个要求,调用会直接跳转异常:轻则程序崩溃、返回DOS时出现乱码或死机,重则破坏DOS内核维护的内存链,导致整个系统锁死需要重启。
只有单段结构的.COM程序能天然满足这个要求——COM格式程序加载时,DOS会把CS/DS/ES/SS四个段寄存器全部初始化为PSP段基址,所以写几十字节的微型COM程序时直接调INT 20H看起来能正常运行,但只要程序涉及多段代码、使用EXE格式、或者运行过程中修改过CS值,调用就会直接出问题。MOV AX,4C00H+INT 21H是DOS 2.0版本正式推出的标准进程终止功能,没有任何寄存器前置要求:不管调用时CS/DS/ES等段寄存器指向什么位置,只要处于当前进程的执行上下文里,DOS内核会直接从自己维护的进程控制块中读取当前进程的PSP地址,完全不依赖用户程序的寄存器状态,几乎没有隐性踩坑的可能。
执行逻辑差异
INT 20H的内部逻辑等价于AH=00H功能号的INT 21H旧版终止调用:执行时仅做最基础的进程跳转回收,不会向父进程传递自定义退出状态,默认返回给父进程(比如COMMAND.COM命令解释器)的退出码固定为0,父进程根本没法通过ERRORLEVEL变量判断程序是正常结束还是运行出错;如果程序运行时没手动关闭打开的文件、修改过PSP中存储的终止向量,还可能出现文件缓冲区内容没刷盘导致数据丢失、内存资源泄漏的问题。AH=4CH功能号的INT 21H调用走的是DOS设计的完整进程退出流程:- 自动回收当前进程占用的所有内存块
- 自动关闭进程打开的所有文件句柄,强制刷新磁盘缓冲区
- 自动恢复父进程的中断向量、DOS维护的PSP链表状态
- 支持通过AL寄存器传递自定义退出码(比如
AL=00代表正常退出,AL=01代表传入参数错误,AL=02代表目标文件不存在等),父进程可以直接读取这个值做后续的批处理逻辑判断。
兼容性差异
INT 20H虽然存在于所有版本的DOS中,但因为调用条件过于苛刻,在DOS 2.0之后推出的多任务环境、内存管理扩展程序、Windows 3.x/9x的虚拟DOS机、第三方DOS兼容环境(比如DR-DOS、DOSBox)中,只要不满足CS=PSP的前置条件,行为完全不可预测,内核层面也没有做容错处理。INT 21H的AH=4CH功能从1983年随DOS 2.0推出后,就成为了所有后续DOS版本、DOS兼容环境、x86平台DOS虚拟机统一支持的标准退出方式,不管是开发者手写汇编程序,还是C/Pascal等高级语言编译生成的DOS程序,全部默认用这个方式退出,不存在兼容断层。
补充常见误区:不少早期汇编教程会提到“程序开头把PSP段首的0偏移字压栈,结尾用RET实现退出”的写法,本质和直接调用
INT 20H的逻辑完全一致,同样要求CS指向PSP段,稳定性远不如4CH调用。
内容的提问来源于stack exchange,提问作者Carl Eric Doromal
相关产品推荐
相关产品推荐

