汇编语言响应中断的特殊情况

  在执行完向 ss 寄存器传送数据的指令后,即便是发生中断,CPU 也不会响应。这样做的原因是,ss:sp 联合指向栈顶,而对它们的设置应该连续完成。如果在执行完设置 ss 的指令后,CPU 响应中断,引发中断过程,要在栈中压入标志寄存器、CS 和 IP 的值。而 ss 改变,sp 并未改变,ss:sp 指向的是不正确的栈顶,将引起错误。所以 CPU 在执行完设置 ss 的指令后,不响应中断。这给连续设置 ss 和 sp 指向正确的栈顶提供了一个时机。即,我们应该利用这个特性,将设置 ss 和 sp 的指令连续存放,使得设置 sp 的指令紧接着设置 ss 的指令执行,而在此之间,CPU 不会引发中断过程。比如,我们要将栈顶设为 1000:0,应该:

  mov ax,1000h
  mov ss,ax
  mov sp,0

  而不应该

  mov ax,1000h
  mov ss,ax
  mov ax,0
  mov sp,0

  Debug 利用单步中断来实现 T 命令的功能,也就是说,用 T 命令执行一条指令后,CPU 响应单步中断,执行 Debug 设置好的处理程序,才能在屏幕上显示寄存器的状态,并等待命令的输入。而在 mov ss,ax 指令执行后,CPU 根本就不响应任何中断,其中也包括单步中断,所以 Debug 设置好的用来显示寄存器状态和等待输入命令的中断处理程序根本没有得到执行,所以我们看不到预期的结果。
完整的自定义中断处理程序

assume cs:code
code segment
 
start:
    mov ax,cs
    mov ds,ax
    mov si,offset do0   ;设置 ds:si 指向源地址
     
    ;设置中断向量
    mov ax,0
    mov es,ax
    mov word ptr es:[0], 200h
    mov word ptr es:[2],0
     
    mov ax,0
    mov es,ax
    mov di,200h         ;设置 es:di 指向目的地址
 
    mov cx,offset do0end - offset do0   ;设置 cx 为传输长度
    cld
    rep movsb
     
    mov al,10
    mov ah,0
    div ah
     
    mov ax,4c00h
    int 21h
 
do0:
    jmp short do0start
    db  "overflow!"
do0start:
    mov ax,cs
    mov ds,ax
    mov si,202h ;设置 ds:si 指向字符串
     
    mov ax,0b800h
    mov es,ax
    mov di,12*160 + 36*2    ;设置 es:di 指向显存空间的中间位置
     
    mov cx,9
s:
    mov al,[si]
    mov es:[di],al
    inc si
    add di,2
    loop s
     
    mov ax,4c00h
    int 21h
 
do0end: nop
code ends
end start

发布日期:

所属分类: 易语言 标签: