michael2ou 发表于 2011-8-9 22:50:38

关于《王爽汇编》第15章 外中断 编写int 9中断例程的一个题目

本帖最后由 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号单元指向的地址
         pop word ptr es:
         push word ptr es:
         pop word ptr es:
         
         
         mov word ptr es:,204h;将中断向量表9号单元指向的地址改为0000:0204H
         mov word ptr es:,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:
         
         cmp al,1
         jne int9ret
         
         mov ax,0b800h
         mov es,ax         
         inc byte ptr es:
         
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:,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    ;sbbdx-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键时,为什么没有改变颜色????




ytrfamli 发表于 2011-8-9 22:50:39

本帖最后由 ytrfamli 于 2011-12-22 14:41 编辑

①这个程序没有反应主要是这里的问题.
首先,
mov di,204h
...
rep movsb
push word ptr es:
pop word ptr es:
...我们知道,rep movsb是会修改di的,在这条指令执行过後,
di已经不是204h,因此紧接着用到di来push pop所备分的
原int9中断地址被存到错误的内存地址去了.
其实经过rep指令,这里也用不到di了,
倒不如直接填进200h,202h省事.

接下来是替身的int9中断例程
push bx
popf
call dword ptr ds:
这里我们想要取得存在内存0000:0200的CS:IP调用原本的int9,
但是ds没有经过初始化,也就是说,基本上
无法确定实际执行时CS:IP跳到哪去了.

②这个没什麽大问题,只有

mov es:,al
应该是
mov es:,al 才对,每160字节一行,不是每120字节


补充:
更改中断向量表9号单元的地址的地方
mov word ptr es:,204h
mov word ptr es:,0
书上的练习建议开头加cli指令,尾巴加sti指令
把这两行mov代码夹起来,禁止可屏蔽中断,
以免这两条指令执行到一半因为按到键盘触发一个不正确的int9
(为什麽?因为这个时候在中断表纪录的int9入口我们才改到一半.)

补补充:
恩...似乎使用debug调试安装int9的程序容易导致崩溃
(就算用g一次走过改写中断表的部分,避免单步调试触发中断还是一样,
不晓得是为什麽,如果有网友知道原因或是有一些分析我愿闻其详.)
建议是把上面这些小bug改正之後直接执行.

michael2ou 发表于 2011-8-11 21:36:07

:'(各位鱼友,拜托!!帮帮我!!!!!!

seuer126 发表于 2011-9-15 14:58:49

还没学到那一章,我先飘过!

rxvey74 发表于 2011-9-18 06:44:59

头大~~~~~``http://www.pgpop.com/image/face1.gif




















http://bbs.hangzhou.com.cn/images/default/sigline.gif
尤美防辐射服怎么样
页: [1]
查看完整版本: 关于《王爽汇编》第15章 外中断 编写int 9中断例程的一个题目