如何让已经驻留在内存的程序退出并卸载?

ykk99114 2007-06-10 08:02:20
用汇编写了个可以驻留内存的程序,现在出不来了,不知道怎样卸载它?有人能解释一下应该怎样退出和卸载么?如果COM和EXE不一样请分别说一下~~
...全文
687 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
主要实现方式就是由程序的第二个实例给驻留的实例发一个退出信号(自定义的),然后自己就终止了。
驻留的实例收到退出信号,首先检测能否退出,如果能退出:
1. Int 21h ax=50h切换PID为自己的PSP(驻留时保存的);
2. 释放资源(恢复自己修改过的中断向量、释放动态分配的内存、关闭打开的文件Handles等);
3. 使用正常的DOS终止来结束程序(INT 21h AH=4Ch)。
zara 2007-06-12
  • 打赏
  • 举报
回复
判断是否驻留, 一般地有两个方法. 一个是程序截留某个中断的特殊的功能号, 返回一个特殊的值. 因为一般的中断调用, 对于不支持的功能都是直接返回的, 所以返回了一个自己预设的特殊值的话, 就认为是自己已经驻留了, 当然了, 还要同时返回已经驻留的地址. 这个方法还是有些风险的, 主要是功能号的选择, 以及不同驻留程序间极少可能的冲突. 另外一个方法, 就是遍历内存块, 检测在特定的位置是否含义自己的特征字符串.
也许, 对初涉驻留来说, 可能简单地检测被截留中断入口也是个方法. 不过, 这个是比较不周全的. 因为, 有可能在自己驻留后, 另外的其它程序驻留也拦截了这个中断.
zara 2007-06-12
  • 打赏
  • 举报
回复
这个方法就是上面提及的最后一个方法.

dos 程序的命令行参数在 PSP:80h 处. 字节 80h 为后面部分的有效字节数; 81h 开始就是命令行参数的字符串, 不包括程序名称自身. 具体你用 debug 带参数调试自己的程序是看下就明白了
ykk99114 2007-06-12
  • 打赏
  • 举报
回复
我用了这个方法判断驻留,理论上不知行不行,实际我用是可以:先读出1CH的中断地址,跟ADD55的偏移量比较一下(COM文件不用管段地址了吧),相等的话表明之前已经驻留过并修改了这个中断向量。只有在程序卸载的时候才把原来的中断地址改回去。

所以还是回到不知怎样卸载程序的问题,想到是用加参数的方式或者组合键让它卸载,可惜刚学,没有理论基础,无从下手~~~
ykk99114 2007-06-11
  • 打赏
  • 举报
回复
这个就是具体的程序,初学汇编,写出这个程序发现问题不少,虽然可以驻留内存显示,但是用上下键选择最近执行过的命令没用,执行EDIT出现异常,本来想按CTRL+Q退出并卸载,可惜还不懂。取时间本来可以直接系统调用,这里尝试一下自己取时间
time segment
org 100h
assume cs:time,ds:time,ss:time

start proc near
jmp begin
oldseg dw ?
oldoff dw ?
ms dw 0
sec db 0
min db 0
hr db 0
begin: mov ah,35h
mov al,1ch
int 21h;取中断
mov oldseg,es
mov oldoff,bx

lea dx,add55
mov ah,25h
mov al,1ch
int 21h;设置新中断
in al,21h
and al,11111100b
out 21h,al
sti
jmp tsr

back: mov ah,8;8=ctrl+q,目前这段无效,还不知如何卸载
int 21h
cmp al,11h
jne back

mov dx,oldoff
mov ax,es
mov ds,ax
mov ax,251ch
int 21h
int 20h

start endp
add55 proc near
push ax
push bx
push cx
push dx
push si
push di
push bp
push ds
push es
sti
add ms,55
cmp ms,1000
jge exit
sub ms,1000
call near ptr gettime
call near ptr disp
exit: cli
pop es
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret
add55 endp
disp proc near
push ax
push cx
push dx
push es
mov ax,0b800h
mov es,ax

disp_s: mov al,sec
xor ah,ah
mov cl,10
div cl
add al,30h
mov es:[0f94h],al
add ah,30h
mov es:[0f96h],ah

disp_m: mov al,min
xor ah,ah
mov cl,10
div cl
add al,30h
mov es:[0f8eh],al
add ah,30h
mov es:[0f90h],ah

disp_h: mov al,hr
xor ah,ah
mov cl,10
div cl
add al,30h
mov es:[0f88h],al
add ah,30h
mov es:[0f8ah],ah
disp_: mov al,':'
mov es:[0f8ch],al
mov es:[0f92h],al
pop es
pop dx
pop cx
pop ax
ret
disp endp
tsr: mov dx,offset tsr
int 27h
jmp back
gettime proc near
push ax
push bx
push cx
push dx
push es
;mov ax,data
;mov ds,ax
xor ax,ax
mov es,ax
mov dl,es:[46eh]
mov dh,es:[46fh]
mov al,es:[46ch]
mov ah,es:[46dh]
mov bx,91
div bx;ax有几个5秒,余数DX/18.2就是秒数
mov cx,dx
mov bx,5
mul bx
push dx
push ax
mov ax,cx
mul bx
mov bx,91
div bx
pop cx
add ax,cx
pop dx;ds:ax=secs
mov cx,3600
div cx
mov hr,al
mov ax,dx
mov cl,60
div cl
mov min,al
mov sec,ah
pop es
pop dx
pop cx
pop bx
pop ax
ret
gettime endp
time ends
end start
zara 2007-06-11
  • 打赏
  • 举报
回复
卸载驻留程序, 先恢复截留的资源, 比如中断, 然后是是否自身占用的内存, 如果驻留前没用是否环境块内存的话, 这时也要一并释放
ykk99114 2007-06-11
  • 打赏
  • 举报
回复
楼上的第一点,本来考虑驻留的东西越少越好,可能是自己刚学没经验
楼上的第二点恢复原来的中断向量,是有考虑过的,不过就是不懂要在什么地方恢复,add55是每55ms执行一次,要恢复的话应该是退出卸载的时候恢复吧,问题又回到不知道怎么卸载了~~
楼上第三点,判断是否已经驻留,无从下手,想过用一个变量来标记,不过每次执行的时候这个变量不就又重新定义赋值了么?能不能说的详细点?
zara 2007-06-11
  • 打赏
  • 举报
回复
1. gettime 子程应该放到 tsr: 之前! 否则, gettime 子程部分不被完全驻留, 系统会错乱的.

2. 自己的 int1ch 部分, 应该在执行了自己的功能后, 转去原来的 int1ch 部分, 以保持功能的延续, 虽然缺省的 int1ch 只是个 iret 指令. 这样要求 oldoff 定义在 oldseg 的前面

3. 驻留程序的撤离, 一般是由再次允许该程序时实现, 可用通过加参数的方法来判别究竟是驻留还是撤离. 当然了, 两个功能都要有释放已经驻留的检查. 这样做, 相比较有驻留部分来实现的优点就是要考虑的方面比较简单. 检测到有驻留, 恢复原来的 int1ch 向量, 释放程序的环境变量块已经程序本事的内存就可用了. 如果由驻留来实现, 需要检测是否 dos 重入, 这个往往比较烦人, 完善的处理起来比较前面一个方法, 就不太值得了, 能免就免
ykk99114 2007-06-10
  • 打赏
  • 举报
回复
比如用组合键让它卸载,程序是实模式下的

21,494

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧