中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 请问哪位知道int 27h或者int 21h的31h号功能的原理?
作者:
标题: 请问哪位知道int 27h或者int 21h的31h号功能的原理? 上一主题 | 下一主题
dafengqixi
初级用户





积分 54
发帖 17
注册 2009-11-27
状态 离线
『楼 主』:  请问哪位知道int 27h或者int 21h的31h号功能的原理? [已使用 LLM 解释]

请问哪位知道int 27h或者int 21h的31h号功能的原理,也就是让一段程序在内存中驻留是怎么实现的,和系统有哪些关系,要是能给出源码更好,谢谢各位了
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 ; size为要申请的内存大小
INT 21H
JC error ; 如果申请内存失败,跳转到错误处理
MOV ES, AX ; 将申请到的内存段地址保存到ES寄存器
  • 复制程序代码到新内存空间
    • 将原程序中需要驻留的部分复制到新申请的内存空间中。假设原程序的当前代码段为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 ; 参数长度为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 27H中断实现驻留

这里不需要像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:
    ; 计算要驻留的大小,这里简单计算从当前代码开始到msg的大小等,实际需要准确计算
    MOV AX, @DATA
    MOV DS, AX
    MOV AH, 48H
    MOV BX, 100H ; 假设要申请100H字节的内存
    INT 21H
    JC ERROR
    MOV ES, AX
    ; 复制代码到新内存空间
    MOV SI, OFFSET START
    MOV DI, ES:OFFSET START
    MOV CX, 100H
    CLD
    REP MOVSB
    ; 设置中断向量(这里简单示例,假设设置中断号20H)
    MOV AX, SEG MY_INT_HANDLER
    MOV DS, AX
    MOV DX, OFFSET MY_INT_HANDLER
    MOV AH, 25H
    MOV AL, 20H
    INT 21H
    ; 调用INT 21H功能号31H实现驻留
    MOV AH, 31H
    MOV DX, 0
    MOV AL, 0
    INT 21H
ERROR:
    MOV AH, 4CH
    INT 21H

MY_INT_HANDLER PROC
    ; 这里是自定义中断处理程序的代码,例如可以显示msg等
    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 ; 先执行一些操作,然后调用INT 27H
    MOV AH, 27H
    INT 21H ; 执行INT 27H实现内存驻留
    MOV AH, 4CH
    INT 21H
END START

这个示例中,程序先显示一条消息,然后调用INT 27H实现内存驻留,不需要复杂的内存申请和复制等操作,系统会自动处理内存驻留相关事宜。



2010-3-10 16:48
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: