鱼C论坛

 找回密码
 立即注册
查看: 1714|回复: 0

关于int 9中断

[复制链接]
发表于 2013-4-11 18:00:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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中断是不可以直接用的吗,一定要通过新的子程序来转的吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 20:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表