LLM 解释
1. INT 21H功能号31H的原理与内存驻留实现
1.1 INT 21H功能号31H简介
INT 21H是MS - DOS中断调用,功能号31H用于实现程序的内存驻留(TSR,Terminate and Stay Resident)。其基本原理是:程序在执行到功能号31H的中断调用时,会将自身的一部分代码和数据保留在内存中,然后终止程序的当前执行,但保留部分仍然可以响应系统的相关中断等操作。
1.2 实现步骤
-
保存内存空间
- 首先,程序需要确定要驻留的内存大小。一般来说,会计算出程序中需要保留在内存中的代码、数据等的字节数。例如,假设要驻留的部分大小为
size
字节。
- 然后,使用
AH = 48H
功能号来申请内存空间。在汇编中,代码大致如下:
MOV AH, 48H
MOV BX, size
INT 21H
JC error
MOV ES, AX
-
复制程序代码到新内存空间
- 将原程序中需要驻留的部分复制到新申请的内存空间中。假设原程序的当前代码段为
CS
,要复制的起始地址为CS:源起始偏移
,目标地址为ES:目标起始偏移
,可以使用串操作指令来完成复制,例如:
MOV SI, 源起始偏移
MOV DI, 目标起始偏移
MOV CX, size
CLD
REP MOVSB
-
设置中断向量(可选,根据是否需要响应自定义中断)
- 如果程序需要响应自定义的中断来实现驻留后的功能,需要设置中断向量。例如,要将自定义中断处理程序
my_int_handler
的偏移和段地址设置到中断向量表中。首先获取要设置的中断号,假设为n
,然后:
MOV AX, SEG my_int_handler
MOV DS, AX
MOV DX, OFFSET my_int_handler
MOV AH, 25H
MOV AL, n
INT 21H
-
调用INT 21H功能号31H实现驻留
- 最后,调用INT 21H功能号31H来实现驻留。其中,
DX
寄存器需要设置为驻留后程序的参数长度(一般为0),AL
寄存器设置为0(表示正常驻留):
MOV AH, 31H
MOV DX, 0
MOV AL, 0
INT 21H
2. INT 27H的原理
2.1 INT 27H简介
INT 27H也是一个MS - DOS中断,它的功能是实现程序的无条件内存驻留。它不需要像INT 21H功能号31H那样先申请内存再复制等复杂步骤。
2.2 实现原理
- 当程序执行INT 27H中断时,系统会自动将当前程序的代码段开始的一定长度的程序代码驻留内存。具体来说,系统会找到当前程序在内存中的位置,然后计算出要驻留的大小(通常是从程序开始到当前代码位置的大小),将这部分代码保留在内存中,然后终止程序的当前执行,但保留部分仍然可以存在于内存中。其大致的汇编代码示例如下:
MOV AH, 27H
INT 21H
这里不需要像INT 21H功能号31H那样进行内存申请和复制等操作,INT 27H内部已经处理了这些细节来实现程序的内存驻留。
3. 与系统的关系
3.1 内存管理方面
- INT 21H功能号31H和INT 27H都涉及到对内存的操作。INT 21H功能号31H需要显式地申请内存空间并复制程序代码到新空间,而INT 27H则是系统自动处理内存驻留相关的内存管理细节。它们都需要遵循MS - DOS的内存管理机制,确保驻留的程序不会与系统其他部分的内存使用冲突,例如不会覆盖系统关键数据结构所在的内存区域。
3.2 中断系统方面
- 对于INT 21H功能号31H,如果程序设置了自定义中断向量,那么就会利用系统的中断向量表来让自定义中断能够被系统正确响应。而INT 27H驻留的程序如果要与系统交互,可能会通过系统提供的中断调用(如INT 21H的其他功能号)来实现,同时系统也会维护中断向量表来保证正常的系统中断功能不受影响。
3.3 程序执行流程方面
- 当程序通过INT 21H功能号31H或INT 27H实现驻留后,原程序的当前执行流程终止,但驻留部分仍然在内存中。系统会继续正常运行其他程序或处理系统任务,而驻留的程序可以在合适的时候(如响应相关中断时)恢复执行相关功能,从而实现程序在内存中的“驻留”功能,继续发挥作用。
4. 示例源码(以INT 21H功能号31H实现简单内存驻留为例)
.MODEL SMALL
.STACK 100H
.DATA
msg db 'This is a TSR program', '$'
.CODE
START:
MOV AX, @DATA
MOV DS, AX
MOV AH, 48H
MOV BX, 100H
INT 21H
JC ERROR
MOV ES, AX
MOV SI, OFFSET START
MOV DI, ES:OFFSET START
MOV CX, 100H
CLD
REP MOVSB
MOV AX, SEG MY_INT_HANDLER
MOV DS, AX
MOV DX, OFFSET MY_INT_HANDLER
MOV AH, 25H
MOV AL, 20H
INT 21H
MOV AH, 31H
MOV DX, 0
MOV AL, 0
INT 21H
ERROR:
MOV AH, 4CH
INT 21H
MY_INT_HANDLER PROC
MOV AH, 09H
LEA DX, msg
INT 21H
IRET
MY_INT_HANDLER ENDP
END START
这个示例中,首先申请内存,复制代码到新内存空间,设置中断向量,然后调用INT 21H功能号31H实现内存驻留。同时定义了一个简单的自定义中断处理程序MY_INT_HANDLER
,当响应中断号20H时会执行该处理程序来显示消息。当然,实际应用中需要根据具体需求准确计算驻留大小、处理更复杂的逻辑等。而如果使用INT 27H实现内存驻留,代码会更简单,例如:
.MODEL SMALL
.STACK 100H
.DATA
msg db 'This is a TSR program using INT 27H', '$'
.CODE
START:
MOV AH, 09H
LEA DX, msg
INT 21H
MOV AH, 27H
INT 21H
MOV AH, 4CH
INT 21H
END START
这个示例中,程序先显示一条消息,然后调用INT 27H实现内存驻留,不需要复杂的内存申请和复制等操作,系统会自动处理内存驻留相关事宜。