|
10鱼币
本帖最后由 michael2ou 于 2011-8-14 22:24 编辑
关于《王爽汇编》第15章 外中断 15.4节 编写int 9中断例程的一个题目题目:在屏幕中间依次显示"a"~"z",并可以让人看清。在显示的过程中,按下Esc键后,改变显示的颜色。
Q:问题在最后面!!
先看看本人的做法:
①先将下面的程序编译运行——将int9程序安装在0000:0204H中
assume cs:code
code segment
start: mov ax,code
mov ds,ax
mov si,offset int9
mov ax,0
mov es,ax
mov di,204h
mov cx,offset int9end-offset int9
cld
rep movsb
push word ptr es:[9*4] ;保存中断向量表中9号单元指向的地址
pop word ptr es:[di-4]
push word ptr es:[9*4+2]
pop word ptr es:[di-2]
mov word ptr es:[9*4],204h ;将中断向量表9号单元指向的地址改为0000:0204H
mov word ptr es:[9*4+2],0
mov ax,4c00h
int 21h
;--------------------int 9程序
int9: push ax
push bx
push es
in al,60h
pushf
pushf
pop bx
and bh,11111100b ;将IF,TF设置为零
push bx
popf
call dword ptr ds:[200h]
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
int9end: nop
code ends
end start
②编译运行上面的程序后,在运行下面的程序!!
assume cs:code
code segment
start: mov ax,0b800h
mov es,ax
mov al,'a'
s: mov es:[120*12+40*2],al
call delay
inc al
cmp al,'z'
jna s
mov ax,4c00h
int 21h
;delay相当于实现了 1000*10000h次循环 相当于下面c语言程序
; for(int i=0;i<1000;i++)
; {
; for(int j=0;j<10000;j++)
; {
; --------
; }
; }
delay proc near
push ax
push dx
mov dx,1000h ;dx 为外层循环
mov ax,0 ;ax 为内层循环
s1: sub ax,1
sbb dx,0 ;sbb dx-0-CF ax有进位时dx才减一
cmp ax,0
jnz s1
cmp dx,0 ;当ax减10000h次是,dx才减一次
jnz s1
pop dx
pop ax
ret
delay endp
code ends
end start
;-----------------------------------------------------end------------------------
Q:在执行依次显示"a"~"z"这程序的过程中,按下Esc键时,为什么没有改变颜色????
|
最佳答案
查看完整内容
①这个程序没有反应主要是这里的问题.
首先, 我们知道,rep movsb是会修改di的,在这条指令执行过後,
di已经不是204h,因此紧接着用到di来push pop所备分的
原int9中断地址被存到错误的内存地址去了.
其实经过rep指令,这里也用不到di了,
倒不如直接填进200h,202h省事.
接下来是替身的int9中断例程 这里我们想要取得存在内存0000:0200的CS:IP调用原本的int9,
但是ds没有经过初始化,也就是说,基本上
无法确定实际执行时CS:IP ...
|