ASM - Note: 内中断,中断处理程序,中断向量表,中断过程。安装、设置中断向量,单步中断。编写 0 号中断的处理程序。
- Created on 2014-11
- 教材:《汇编语言》(第二版)王爽 著 清华大学出版社
中断:CPU不再接着(刚执行完的指令)向下执行
当8086 CPU发生以下情况时,将产生马上处理的中断信息:
int
右边数字为中断类型码:
- 除法错误(执行div时产生溢出) - 0
- 单步执行 - 1
- 执行into指令 - 4
- 执行int指令 - 该指令的格式为 int n
- 指令中n为byte型立即数,是提供给CPU的中断类型码
根据中断类型码,定位相应中断处理程序
中断向量表,存储256个中断处理程序的 入口地址(CS:IP)
- 它在内存中存放,对于8086PC机,放在内存地址0处
- 在0000:0000~0000:03FF,CS、IP地址分别都是dword,共占4B
- 从中断信息中,取得中断类型码 N
- 标志寄存器的值入栈,pushf
- 因为中断过程中要改变标志寄存器的值,要先将其保存在栈中
- 将标志寄存器的第8位 TF 和 第9位 IF 的值 设置为 0
- TF = 0, IF = 0(目的日后详述)
- CS 的内容 入栈,push cs
- IP 的内容 入栈,push ip
- 设置中断处理程序的入口地址
IP = (中断类型码 * 4) ; 用地址为 中断类型码 * 4 的内存内容 设置IP
CS = (中断类型码 * 4 + 2) ; 类上
然后执行中断处理程序
iret 功能:
pop ip
pop cs
popf
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
;0000:0000~0000:03FF 为中断向量表
;而0200~02FF还不被其它程序包括OS等使用
;可以安全使用
**;传输长度
mov cx, offset do0end - offset do0
cld ;设置传输方向为正
rep movsb ;安装程序**
;设置中断向量表
mov ax, 0
mov es, ax
**mov word ptr es:[0 * 4], 200h ;ip
mov word ptr es:[0 * 4 + 2], 0 ;cs**
mov ax, 4c00h
int 21h
do0:
jmp short do0start
db 'Overflow!'
do0start:
;指向上面定义的那串字符
mov ax, cs
mov ds, ax
mov si, 202h
;指向显示空间的中间位置
mov ax, 0b800h
mov es, ax
mov di, 12 * 160 + 36 * 2
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
Attachment 附件:汇编语言第十二章安装关于除法溢出的中断程序的实例.asm
使 TF = 1,CPU将工作于 单步中断 方式下,执行完这条指令后,就引发单步中断
当然,进入中断处理程序前,设置TF = 0,避免在中断处理程序执行中发生单步中断
在执行完向 ss 寄存器传送数据的指令后,即便发生中断,CPU也不会响应
主要原因:
- ss:sp 联合指向栈顶,而对它们的设置应该连续完成。
- 因为假如设置完ss后被中断,需要压栈保存数据,
- 此时后续设置sp的语句没有执行,于是中断处理保存了错误的sp。
- 中断恢复后,会导致sp没有指向正确的栈顶!
- 所以设置sp的语句,紧跟设置ss的语句!
编写0号中断的处理程序,使得在出发溢出发生时,在屏幕中间显示字符串“divide error!”,然后返回到DOS。
类同12.10小节下的程序
assume cs:code
code segment
start:
mov ax, cs ;cs 曾错写为 offset do
mov ds, ax
mov si, offset do ;offset do 曾错写为 0
mov ax, 0
mov es, ax
mov di, 200h
mov cx, offset do_end - offset do
cld
rep movsb
mov word ptr es:[0 * 4], 200h ;ip
mov word ptr es:[0 * 4 + 2], 0 ;cs
mov ax, 1000
mov bh, 1
div bh
mov ax, 4c00h
int 21h
do:
mov ax, 0
mov ds, ax
mov si, 200h + offset msg - offset do
mov ax, 0b800h
mov es, ax
mov di, 12 * 160 + 2 * (40 - (offset do_end - offset msg) / 2)
mov cx, offset do_end - offset msg
s:
mov al, ds:[si]
mov es:[di], al
inc si
add di, 2
loop s
mov ax, 4c00h
int 21h
msg:
db "divide error!" ;13字
do_end:
nop
code ends
end start
后记:
- 趁着对12.10小节的中断处理程序的安装程序还有印象时,重写的。不够独立。
- 竟然对照12.10小节的程序来debug!不能容忍有下次!
Attachment 附件:汇编语言第十二章实验10.asm