各位哥哥帮忙看一下我的程序!

fiendishman 2003-09-14 04:48:50
一个重写键盘中断的程序,下面是简单结构,重新定义F10键,按下F10后显示
一句话,要求驻留内存中。写中断时没什么问题,但在驻留内存时始终有问题,
麻烦各位大虾帮忙看看我的程序,谢谢。小弟初学汇编,各位哥哥不要见笑。
data segment
assume cs:data
mes1 db 'Press F1--F9 to show message',0dh,0ah,'$'
mes2 db 'Press F10 to quit!',0dh,0ah,'$'
mes3 db 'Please input your choise from F1--F10:',0dh,0ah,'$'
mes4 db '***I love you!Do you love me too?',0dh,0ah,'$'
mes5 db 'Restain the program!',0dh,0ah,'$'
mes6 db 'System Restore!',0dh,0ah,'$'
old09ip dw ?
old09cs dw ?
Oldint9 dd ?
intsb proc near
sti
cld
in al,60h
mov bl,al
cmp bl,44h
jne aa
call F10sb
aa:call F19sb
intsb endp
F19sb proc near
sti
mov ah,9
mov dx,offset mes4
int 21h
call cs:Oldint9 想利用原来的中断响应代码,但好象没什么用?
iret
F19sb endp


F10sb proc near

cli
push ds ;restore old int 09
mov dx,old09ip
mov ax,old09cs
mov ds,ax
mov al,09h
mov ah,25h
int 21h
pop ds
sti
mov ah,9
mov dx,offset mes6
int 21h
mov ah,4ch ;return to DOS
int 21h
iret
F10sb endp
data ends

endresident segment
endresident ends

code segment
main proc far
assume cs:code,ds:data

PSP dw ?

start:
mov cs:PSP,ds
mov ax,data
mov ds,ax
;save old int
mov ds,ax
mov ax,0
mov es,ax
cli
mov ax,es:[9h*4]
mov word ptr Oldint9,ax
mov ax,es:[9h*4+2]
mov word ptr Oldint9+2,ax
mov al,09h
mov ah,35h
int 21h

mov old09ip,bx
mov old09cs,es
push ds ;save ds
;set new int vector
lea dx,intsb
mov ax,seg intsb
mov ds,ax
mov al,09h
mov ah,25h
int 21h
pop ds ;restore ds

;set mask bits
in al,21h
and al,0fdh
out 21h,al

sti

mov ah,9
mov dx,offset mes1
int 21h
mov ah,9
mov dx,offset mes2
int 21h
mov ah,9
mov dx,offset mes3
int 21h
mov di,20000
a: mov si,30000
b: dec si
jnz b
dec di
jnz a
mov dx,endresident
sub dx,cs:PSP

mov cl,4
shr dx,cl /这里不知道对不对,因为程序运行时
mov ax,3100h 中断是可响应的,但程序结束后按键却出来
int 21h 一堆乱码。
code ends
end main
...全文
28 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
dunkel 2003-09-16
  • 打赏
  • 举报
回复
楼主的驻留长度是400h节(16KB), 虽然不是根据实际的情况计算出来的, 但对它这个程序而言绝对足够了, 所以应该不是这个问题.
ahjoe 2003-09-16
  • 打赏
  • 举报
回复
驻留长度的计算是有问题的。
dunkel 2003-09-16
  • 打赏
  • 举报
回复
不一定主要是指发生键盘中断时的位置, 由于中断处理自身不会重置 ds 的, 所以如果是从你的代码中发生的, ds 是指向你的 DATA 段, 但如果是从其他程序甚至是 os 内核中发生的呢? 那时的 ds 指向的那个程序或 os 自己的数据段, 不再是你的那个 DATA 段. 但使用 cs: 段前缀就没有这个问题, 这时的 cs 指向的肯定是你的这个 CODE 段, 因为现在就是在这里运行的啊. 当然除了使用 cs: 的段前缀外, 重新设置 ds 以指向自己的 DATA 段也是个方法, 注意要先保存 ds 再使用, 最后还得恢复.
W32API 2003-09-15
  • 打赏
  • 举报
回复
是的
shajw 2003-09-15
  • 打赏
  • 举报
回复
>> M12:call ds:old_io
这时的 ds 不一定是指向 DATA 段的, 所以就会转移到错误的地方去, 死机了.
不一定,怎么理解?是语法上有问题吗?如果没有问题,不存在二意性啊?为什么会有不一定一说?
如果按照你说的那样做,也不能解决死机的问题,问题依然存在!

dunkel 2003-09-15
  • 打赏
  • 举报
回复
>> M12:call ds:old_io
这时的 ds 不一定是指向 DATA 段的, 所以就会转移到错误的地方去, 死机了. 所以一般的做法是将 old_io 放在 CODE 段中, 用 jmp cs:old_io 转移到原来的中断处理入口.
dunkel 2003-09-15
  • 打赏
  • 举报
回复
>> M12:call ds:old_io
这时的 ds 实际上并不能保证指向 DATA 段, 所以直接的后果就是 call 到了一个错误的地方, 就死机了. 所以一般的做法是将 old_io 放在 CODE 段中, 用 jmp cs:old_op 来转移到原来的中断入口, 后面的处理就是它的事情了, 除非你对处理后的结果感兴趣, 一般是不用 call 来调用原来的中断处理程序的.
shajw 2003-09-15
  • 打赏
  • 举报
回复
在dos下可以随意对内存进行修改,但在WINDOWS中这样做是不允许的,对内存的修改会被WINDOWS认为是非法操作!
fiendishman 2003-09-15
  • 打赏
  • 举报
回复
谢谢!
下面是我重新做的程序,中断和驻留都可以解决,但是在利用CALL 调用原中断的处理时死机
麻烦大家帮我看看,不知道和使用的操作系统有没有关系?(我在宿舍用的是xp中的dos)

DATA SEGMENT
MES1 DB 'DISPLAY A F1',0ah,0dh,'$'
MES0 DB 'EXIT F10',0ah,0dh,'$'
old_io dd ?

DATA ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA
OPTION1 PROC
PUSH AX
PUSH BX
PUSH CX
MOV AH,0FH
INT 10H
MOV AL,41H
MOV BL,07H
MOV CX,12
MOV AH,9
INT 10H
POP CX
POP BX
POP AX
RET
OPTION1 ENDP



OPTION0 PROC
push ax
PUSH BX
push dx
push ds


mov ax,0
mov es,ax
mov bx,36
mov ax,word ptr old_io
mov es:word ptr[bx],ax
mov ax,word ptr old_io+2
mov es:word ptr[bx],ax

mov ah,0fh
int 21h
mov al,4ah
mov bl,07h
mov cx,6
mov ah,9
int 10h
pop ds
pop dx
POP BX
pop ax
ret
OPTION0 ENDP




KEYBOARD PROC FAR

PUSH AX



in al, 60h
test al,80h
jnz EXIT

M1:
CMP AL,3BH ;F1?
JE M2

CMP AL,44H ;F10

JE M11
jmp M12
M2:
CALL OPTION1
JMP EXIT


M11:

CALL OPTION0
JMP EXIT
M12:call ds:old_io

EXIT:cli
in al,61h
or al,80h
out 61h,al
and al,7fh
out 61h,al



mov al,20h
out 20h,al
sti

POP AX
IRET
KEYBOARD ENDP

START:MOV AX,DATA
MOV DS,AX

PUSH DS
mov bx,cx
mov ds,bx
mov al,9
mov ah,35h
int 21h
mov word ptr old_io,bx
mov word ptr old_io[2],es

LEA DX,KEYBOARD
MOV AX,SEG KEYBOARD
MOV DS,AX
MOV AL,09
MOV AH,25H
INT 21H
pop ds


M0:MOV AH,9
MOV DX,OFFSET MES1
INT 21H




MOV DX,OFFSET MES0
INT 21H


mov al,0FDH
out 21H,AL
STI


MOV AH,31H
MOV AL,0
MOV DX,400
INT 21H

CODE ENDS
END START





dunkel 2003-09-14
  • 打赏
  • 举报
回复
1. 自己的 int09h 代码中不要使用 int21h(ah=09h) 来显示信息,
可以用 int10h 的相应的功能来代替;
2. 自己的 int09h 中需要保存 ax 并进行恢复, 因为你的代码使用到了这个寄存器,
卸载模块里涉及到的寄存器更多, 都需先保存然后再恢复的操作;
3. old09ip,old09cs 和 oldint9 只要有一个就足够了, 因为假如只保留oldint9的话,
可以用 word ptr oldint9 和 word ptr oldint9[2] 来存取其 ip 和 cs;
4. 最后计算驻留长度时也有错误, 至少不需要 shr dx, cl
因为那时 dx 及 psp 都已经是以节(para.)为单位的了

21,458

社区成员

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

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