后知淡然 发表于 2011-10-11 15:06:25

关于检测点15.1的问题

(2) 仔细分析程序中的主程序,看看有什么潜在的问题?
在主程序中,如果在设置执行设置int 9中断例程的段地址和偏移地址的指令之间发生了键盘中段,则CPU将转去一个错误的地址执行,将发生错误。找出这样的程序段,改写他们,排除潜在的问题。
书上是这么说的。看完题目后我是在开始保存原int 9程序的时候就设置了if=0。
在网上搜索了相关的答案,都是在设置新的int 9的时候设置if=0
相关代码
assume cs:code

stack segment

   db 128 dup (0)

stack ends

data segment

   dw 0,0

data ends

code segment

start:   mov ax,stack

   mov ss,ax

   mov sp,128



;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中

   mov ax,data

   mov ds,ax



   mov ax,0

   mov es,ax



   push es:

   pop ds:

   push es:

   pop ds:



;在中断向量表中设置新的int 9中断例程的入口地址

   cli         ;设置IF=0屏蔽中断

   mov word ptr es:,offset int9

   mov word ptr es:,cs

   sti         ;设置IF=1不屏蔽中断



;依次显示'a'~'z'

   mov ax,0b800h

   mov es,ax

   mov ah,'a'

s:   mov es:,ah ;第12行第40列

   inc ah

   cmp ah,'z'

   jnb s



;将中断向量表中int 9中断例程的入口恢复为原来的地址

   mov ax,0

   mov es,ax



   push ds:

   pop ss:

   push ds:

   pop es:



;结束

   mov ax,4c00h

   int 21h



;循环延时,循环100000h次

delay:   push ax

   push dx

   mov dx,1000h

   mov ax,0

delay1:sub ax,1

   sbb dx,0      ;(dx)=(dx)-0-CF

   cmp ax,0

   jne delay1

   cmp dx,0

   jne delay1

   pop dx

   pop ax

   ret



;以下为新的int 9中断例程

int9:    push ax

   push bx

   push es



   in al,60h   ;从端口60h读出键盘输入



;对int指令进行模拟,调用原来的int 9中断例程

   pushf            ;标志寄存器入栈

   call dword ptr ds:;CS、IP入栈;(IP)=ds:,(CS)=ds:



;如果是ESC扫描码,改变显示颜色

   cmp al,1      ;和esc的扫描码01比较

   jne int9ret      ;不等于esc时转移



   mov ax,0b800h

   mov es,ax

   inc byte ptr es:;将属性值+1,改变颜色



int9ret:pop es

   pop bx

   pop ax

   iret



code ends

end start


后知淡然 发表于 2011-10-11 15:20:33

   push es:



   pop ds:



   push es:



   pop ds:







;在中断向量表中设置新的int 9中断例程的入口地址



   cli         ;设置IF=0屏蔽中断



   mov word ptr es:,offset int9



   mov word ptr es:,cs



   sti   上例中,是在设置新的int 9中断时将if设置为0。如果在保存中发生中断,那保存的原int 9地址不就会出错?下面的还原也就会出错。麻烦高手讲一下!
页: [1]
查看完整版本: 关于检测点15.1的问题