第十二章 内中断
12.1 内中断的产生
发生情况:
- 除法错误(除法溢出时等)
- 单步执行
- 执行into指令
- 执行int指令
使用中断类型码的数据来标识中断信息的来源。
8086CPU中的中断类型码:
- 除法错误:0
- 单步执行:1
- 执行into指令:4
- 执行int指令
12.2 中断处理程序
12.3 中断向量表
定义:就是中断处理程序入口地址的列表
中断向量表存放着256个中断源所对应的中断处理程序的入口,8086CPU从0000:0000~0000:03FF存放向量表,且不可改变。一个表项,占两个字,高地址存放段地址,低地址存放偏移地址。
检测点 12.1
(1)70:018B
(2)4N,4N+2
12.4 中断过程
定义:CPU硬件通过中断类型码找到中断向量,并设置CS和IP的过程。
- 取得中断类型码
- pushf
- TF=0,IF=0
- push CS
- push IP
- (CS)=(4N+2), (IP)=(4N)
12.5 中断处理程序和iret指令
- 中断处理程序编写步骤:
- 保存用到的寄存器
- 处理中断
- 恢复用到的寄存器
- 用iret指令返回
iret返回:
pop IP
pop CS
popf
12.6 除法错误中断的处理
assume cs:code code segment start: mov ax,1000h mov bh,1 div bh code ends end start
IF (interrupt flag)中断标志位由1变为了0
12.7 编程处理0号中断
一般情况下,0000:0200h~0000:02FF的256个字节的空间中断向量表项都是空的,用来存储我们自己的程序。
12.8 安装
编译器可以处理表达式
12.9 do0
0号中断的处理程序:
- 将显示程序保存地址存储到0000:0200中
- 设置中断向量表:将0000:0200的段地址与偏移地址保存到0*4+2:0*4处
- 编写显示程序
12.10 设置中断向量
mov ax,0 mov es,ax mov word ptr es:[0*4],0200h mov word ptr es:[0*4+2],0
12.11 单步中断
CPU在执行完一段指令之后,如果检测到TF=1,则产生单步中断。
单步中断过程
- 取得中断类型码1
- 标志寄存器入栈,设置TF,IF为0--避免死循环中断
- CS,IP入栈
- (IP)=(1*4),(CS)=(1*4+2)
12.12 响应中断的处理情况
在执行设置ss和sp地址时,当执行到设置ss地址时,如果产生中断,则ss:sp并不是指向正确的栈顶地址,将产生错误。所以CPU在执行完,设置ss指令后,不产生中断,接着执行下一指令。因此我们正确的设置栈地址指令应为:
mov ax,stacksg
mov ss,ax
mov sp,10h
而不是
mov ax,stacksg mov ss,ax mov ax,0 mov sp,10h
实验12 编写0号中断的处理程序
assume cs:code code segment start: mov ax,cs mov ds,ax mov si,offset do0 mov ax,0 mov es,ax mov di,200h mov cx,offset do0end-offset do0 cld rep movsb mov word ptr es:[0*4+2],0 mov word ptr es:[0*4],200h mov ax,4c00h int 21h do0: jmp short do0start db 'Biu OverFlow!' do0start: mov ax,0b800h mov es,ax mov ax,cs mov ds,ax mov si,202h mov di,12*160+36*2 mov cx,13 s: mov al,ds:[si] mov es:[di],al mov byte ptr es:[di+1],4 add di,2 inc si loop s mov ax,4c00h int 21h do0end:nop code ends end start
用了个测试程序
assume cs:code code segment start: int 0 code ends end start
第十三章 int指令
13.1 int指令
int n相当于引发一个n号的中断处理程序,执行过程
- 取中断类型码
- 标志寄存器入栈,TF=0,IF=0
- CS,IP入栈
- (IP)=(4*n),(CS)=(4*n+2)
DOSBOX在调试的时候不会自动显示中断信息,而是跳到一个异常地址,所以我只能先把中断程序提前写入,再调用我们的程序。
assume cs:code code segment start: mov ax,0b800h mov es,ax mov byte ptr es:[13*160+40*2],'!' int 0 code ends end start
13.2 编写供应程序调用的中断例程
问题一:编写,安装中断7ch的中断例程
求一word型数据的平方
例如:2*2345^2
测试用例
assume cs:code code segment start: mov ax,2345 int 7ch add ax,ax adc dx,dx mov ax,4c00h int 21h code ends end start
中断例程
assume cs:code code segment start:
;将程序转移到0000:0200 mov ax, cs mov ds,ax mov si,offset square mov ax,0 mov es,ax mov di,200h mov cx,offset squareend-offset square cld rep movsb ;将程序中断程序入口地址写入中断向量表 mov ax,0 mov es,ax mov word ptr es:[7ch*4+2],0 mov word ptr es:[7ch*4],200h mov ax,4c00h int 21h square: mul ax iret;避免改变标记寄存器等和int组合使用 squareend:nop code ends end start