一般情况下,CPU 在执行完当前指令后,如果检测到中断信息,就响应中断,引发中断过程。可是,在有些情况下,CPU 在执行完当前指令后,即便是发生中断,也不会响应。下面用一种情况来说明。
在执行完向 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