|
主题 : : 关于int 9中断的安装的问题 [待解决] |
回复[ 2次 ]
点击[ 405次 ] | |
荣誉值:0
信誉值:0
注册日期:2009-11-16 13:00 |
不好意思,写错了。
mov ax,stacks
mov ss,ax
mov sp,128 ; set the self stacks
push es:[9*4] ; IP
push es:[9*4+2] ; CS
mov bx,dataseg
mov ds,bx
mov bx,0
pop ds:[bx+2] ; 保存原来的数据 1.
pop ds:[bx] ;2.
; set the new interruption list
cli
mov word ptr es:[9h*4],0200h ;3.
mov word ptr es:[9h*4+2],0h
sti
我不小心把 1 2 写反了,就出错了。 但奇怪的是 在第三条语句处崩溃的。
;=================================================
; 以下为小弟写的代码。
assume cs:codeseg
; 编写一个程序 依次显示 'a' ~ 'z'
dataseg segment
dw 128 dup(0) ;用于存放int 9中断原来的 IP CS
dataseg ends
stacks segment
db 128 dup(0)
stacks ends
codeseg segment
start:
; install int 9 interruption
mov ax,0
mov es,ax
mov di,0200H ; set the destination
mov ax,cs
mov ds,ax
mov ax,offset int9start
mov si,ax ; set the source
mov cx,offset int9ends-offset int9start
cld
rep movsb ; install the int 9 interruption
; set the interruption list
mov ax,stacks
mov ss,ax
mov sp,128 ; set the self stacks
push es:[9*4] ; push original interruption IP
push es:[9*4+2] ; push original interruption CS
mov bx,dataseg ; the place to store original interruption CS and IP
mov ds,bx
mov bx,0
pop ds:[bx+2] ; 保存原来的数据
pop ds:[bx]
; set the new interruption list
cli
mov word ptr es:[9h*4],0200h
mov word ptr es:[9h*4+2],0h
sti
; test the interruption
; 显示 A - Z
mov ax,0B800H
mov es,ax
mov ax,12*160+10*2
mov di,ax ; es:di 指向显存 20H 颜色
mov cx,26
mov ah,'A'
mov byte ptr es:[di+1],20H
s:
mov byte ptr es:[di],ah
inc ah
call delay
loop s
mov ax,4c00h
int 21h
; 延时程序
delay: push ax
push dx
mov dx,2000H
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
; the new interruption 9
int9start:
push ax
; 中断由按键盘引起的 ,硬件会自动调用 int 9, 数据被送往 60H 端口
in al,60H ; 读取数据
; 在使用之前需要 使用 原来的 int 9号中断来 进行一些硬件的设置
; 所以此处需要调用 int 9 中断 ,但不能使用 int 9H 来调用。否则陷入无限的循环中去,自个儿调用自个儿 没有返回。
; 故而 采用模拟 int 9H --> 1. 取中断码(已知) 2. 标志寄存器入栈 3. IF=0 TF=0
; --> 4. CS IP 入栈 5. IP=(N*4) CS=(N*4+2) 需要跳转到原来的int 9H 中断处指向程序,然后返回。
pushf ; 标志寄存器入栈 3. IF TF 已被硬件在调用本中断时 设置为0 了 ,所以不用重复
call dword ptr ds:[0] ;4 5 调用 原始int 9 中断 call --> push cs push ip , cs=[2] ip=[0]
; 处理完后, 处理我们需要的实现
cmp al,1
je increment ;改变颜色
cmp al,9eH ; 满屏都是A
je fillscreen
jmp int9ret
increment:add byte ptr es:[di+1],2 ;改变颜色的程序
jmp int9ret
; 满屏都充满A
fillscreen: push cx
push di
mov di,0
mov cx,2000
fill: mov byte ptr es:[di],'A'
mov byte ptr es:[di+1],30H
add di,2
loop fill
pop di
pop cx
jmp int9ret
; 程序返回
int9ret:
pop ax
iret
int9ends: nop
codeseg ends
end start
;========================================
实现效果是: 程序在
mov ax,0B800H
mov es,ax
mov ax,12*160+10*2
mov di,ax ; es:di 指向显存 20H 颜色 处 循环显示 A-Z
并且 在这期间 按下 A并松开后 满屏充满 A
缺陷: 在程序显示完 Z后, 再按任意键 均会崩溃。 不知道咋整。 | | |