马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
- DATAS SEGMENT
- ;此处输入数据段代码
- DW 0,0
- DATAS ENDS
- STACKS SEGMENT
- ;此处输入堆栈段代码
- DB 256 DUP (0)
- STACKS ENDS
- CODES SEGMENT
- ASSUME CS:CODES,DS:DATAS,SS:STACKS
- START:
- MOV AX,STACKS
- MOV SS,AX
- MOV SP,256
- MOV AX,DATAS
- MOV DS,AX
- MOV AX,0
- MOV ES,AX
- ;将原来的中断例程的入口地址存放到数据段中
- PUSH ES:[9*4]
- POP DS:[0]
- PUSH ES:[9*4+2]
- POP DS:[2]
- ;在中断向量表中设置新的INT9中断例程的入口
- ;放置在设置中断例程的入口地址的时候产生键盘中断
- CLI ;禁止其他的可屏蔽中断
- MOV WORD PTR ES:[9*4],OFFSET INT9
- ;如果我们这边突然产生了键盘中断的话,那么我们的键盘中断
- ;就会指向偏移地址是我们设置的地址,但是段地址是原来的
- ;段地址的一个不同的地址空间,这样就会产生调用了不是我们
- ;所设定的中断例程程序代码段,这当然是一个潜在的问题了,这边
- ;我们应该怎样解决这样的问题呢,现在是使用STI和CLD的时候了
- ;这边我们可以在改变中端例程的入口地址的时候,不允许可屏蔽的
- ;中断产生,所以我们在这两行代码的前后加上两条指令就可以了
- MOV ES:[9*4+2],CS
- STI ;解除可屏蔽中断
- MOV AX,0B800H
- MOV ES,AX
- MOV AH,'A'
- S:
- MOV ES:[160*12+40*2],AH
- CALL DELAY
- INC AH
- CMP AH,'Z'
- JNA S
- ;程序执行完我们想要的效果后,将原来的中断例程的入口地址放回去
- MOV AX,0
- MOV ES,AX
- PUSH DS:[0]
- POP ES:[9*4]
- PUSH DS:[2]
- POP ES:[9*4+2]
- MOV AH,4CH
- INT 21H
- DELAY:
- PUSH AX
- PUSH DX
- MOV DX,1000H
- MOV AX,0
- S1:
- SUB AX,1
- SBB DX,0
- CMP AX,0
- JNE S1
- CMP DX,0
- JNE S1
- POP DX
- POP AX
- RET
- ;下面是新的INT9中断例程
- INT9:
- PUSH AX
- PUSH BX
- PUSH ES
- IN AL,60H
- PUSHF
- ;PUSHF
- ;POP BX
- ;AND BH,11111100B
- ;PUSH BX
- ;POPF
- ;上面的这部分说是可以精简的,因为程序在进入调用
- ;中断例程的时候,就已经置IF,TF为0了
- CALL DWORD PTR DS:[0] ;调用原来的INT 9中断例程,
- ;这边当然是为了原来的系统中,如果我们按了其他的键盘
- ;上面的键的话,可以调用原来的INT 9中断例程,才不会导致
- ;混乱
- CMP AL,1 ;从60端口中读出的是对应的扫描码
- ;如果是想读出控制键或者是切换键
- ;的数据的话我们应该访问0040:17H
- ;端口的状态字节
- JNE INT9RET
- MOV AX,0B800H
- MOV ES,AX
- INC BYTE PTR ES:[160*12+40*2+1]
- INT9RET:
- POP ES
- POP BX
- POP AX
- IRET ;这边的中断返回具体指的应该是我们
- ;按键盘上面的一个键的时候,因为本身调用中断例程的话
- ;中断例程是有这样的代码的,它的操作时POP IP,POP CS,
- ;POPF
- CODES ENDS
- END START
问一下大神,我的代码和他有什么区别 assume cs:code,ss:stack stack segment
db 128 dup (0)
stack ends data segment
dw 0,0
data ends code segment
start: mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:[160*12+40*2],ah
call delay
inc ah
cmp ah,'z'
jna s
call int9
mov ax,4c00h
int 21h
int9:
push ax
push bx
push es
in al,60h
int 9
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret:pop es
pop bx
pop ax
iret
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
code ends
end start int 9中断是不可以直接用的吗,一定要通过新的子程序来转的吗 |