JJ张彬华 发表于 2013-4-11 18:00:58

关于int 9中断


[*]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:
[*]POP DS:
[*]PUSH ES:
[*]POP DS:
[*]
[*];在中断向量表中设置新的INT9中断例程的入口
[*];放置在设置中断例程的入口地址的时候产生键盘中断
[*]CLI ;禁止其他的可屏蔽中断
[*]MOV WORD PTR ES:,OFFSET INT9
[*];如果我们这边突然产生了键盘中断的话,那么我们的键盘中断
[*];就会指向偏移地址是我们设置的地址,但是段地址是原来的
[*];段地址的一个不同的地址空间,这样就会产生调用了不是我们
[*];所设定的中断例程程序代码段,这当然是一个潜在的问题了,这边
[*];我们应该怎样解决这样的问题呢,现在是使用STI和CLD的时候了
[*];这边我们可以在改变中端例程的入口地址的时候,不允许可屏蔽的
[*];中断产生,所以我们在这两行代码的前后加上两条指令就可以了
[*]MOV ES:,CS
[*]STI ;解除可屏蔽中断
[*]
[*]MOV AX,0B800H
[*]MOV ES,AX
[*]MOV AH,'A'
[*]S:
[*]MOV ES:,AH
[*]CALL DELAY
[*]INC AH
[*]CMP AH,'Z'
[*]JNA S
[*]
[*];程序执行完我们想要的效果后,将原来的中断例程的入口地址放回去
[*]MOV AX,0
[*]MOV ES,AX
[*]
[*]PUSH DS:
[*]POP ES:
[*]PUSH DS:
[*]POP ES:
[*]
[*]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: ;调用原来的INT 9中断例程,
[*];这边当然是为了原来的系统中,如果我们按了其他的键盘
[*];上面的键的话,可以调用原来的INT 9中断例程,才不会导致
[*];混乱
[*]
[*]CMP AL,1 ;从60端口中读出的是对应的扫描码
[*];如果是想读出控制键或者是切换键
[*];的数据的话我们应该访问0040:17H
[*];端口的状态字节
[*]JNE INT9RET
[*]
[*]MOV AX,0B800H
[*]MOV ES,AX
[*]INC BYTE PTR ES:
[*]
[*]INT9RET:
[*]POP ES
[*]POP BX
[*]POP AX
[*]IRET ;这边的中断返回具体指的应该是我们
[*];按键盘上面的一个键的时候,因为本身调用中断例程的话
[*];中断例程是有这样的代码的,它的操作时POP IP,POP CS,
[*];POPF
[*]
[*]CODES ENDS
[*]END START
问一下大神,我的代码和他有什么区别assume cs:code,ss:stackstack segment
db 128 dup (0)
stack endsdata segment
dw 0,0
data endscode segment
start: mov ax,0b800h
       mov es,ax
    mov ah,'a'
   
s:   mov es:,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:
   
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中断是不可以直接用的吗,一定要通过新的子程序来转的吗
页: [1]
查看完整版本: 关于int 9中断