8086汇编内中断总结之0号中断和1号中断

内中断: 是CPU内部发生情况后而产生的中断信息,于是CPU便放下手中的活来处理中断例程

8086CPU会产生主要这么几种内中断:

1.除法溢出(0号中断)

2.单步中断(1号中断)

3.执行into指令产生的中断(不清楚)

4.执行int指令产生的中断(常见的int 21就是属于这种)

首先,理解清楚什么是中断例程, 中断向量,中断向量表,中断信息,中断类型码等概念

1.中断类型码是一个8位的数,也就是0-255的范围,一共256个中断类型码,每一个号码对应一个中断向量

2.中断向量里面包含中断例程的入口地址(CS:IP),其中cs是16位段寄存器,ip也是16位的所以一共4字节

3.中断向量表是一张表存储着256个中断向量,而每一个向量存储着一个中断例程的地址,也就是说总共最多会有256个中断例程

4.中断信息包含很多信息最重要的就是中断类型码,该码号指出了中断例程的在内存中的置位

5.中断例程又称为中断处理程序,是CPU在接收到中断信息后所执行的程序,该程序的入口位于中断向量表中的中断向量里

总结一下: 

首先中断例程就可以看做程序,这种程序最多只能有256个,这些程序在发生中断后会被CPU调用,每个程序都有一个相对于的入口地址

这些地址被存放在一张表里叫做中断向量表,因为中断例程最多有256个,所以中断向量表最多也就是256项,而中断向量的地址是如何确定的呢?因为我们只有通过中断向量表才能找到中断例程来处理中断信息

中断向量表在8086CPU中的位置是固定的,位于0000:0000~0000:03ff这1024字节中,然而我们知道一条中断向量是4字节大小,那中断向量表就有1024 / 4 = 256条中断向量

当发生中断时,CPU就会就收到中断信息,中断信息里有很多东西, 其中就包括了中断类型码,这是一种8位的码,正好也一共有256个完全覆盖中断向量表,假设我们收到的中断类型码是8的话, 那么我们通过[8 * 4]和[8 *4 + 2]来确定一条中断向量即其cs:ip, 为何是这样? 首先第八号中断类型码,由于中断类型码是从0开始到255,所以第八号实际处于第九个的置位,而每一条中断向量是4个字节,所以要4 * 8这个地址才是第九个位置的开头即cs的置位,因为cs是16位即2字节所以ip就处在4 * 8 + 2这个地方。

整个过程可以变为:

取得终端类型码N->pushf->TF和IF置零(为了防止外中断和单步中断的产生)->push cs push ip->把cs设置成0000:[8 * 4],ip设置成0000:[8 * 4 + 2]即达到了中断例程的入口执行中断处理程序->使用iret返回

assume cs:code
COMMENT !
由于中断例程不可能到达256个那么多,所以中断向量表中还有很多是空的
比如0000:0200~0000:02FF这256个字节,所以便把中断例程放置在这个位置
!

code segment
start:
;安装中断例程
	mov ax, 0
	mov es, ax
	mov di, 200h   ;目的地址es:di 即0000:0200,
	mov ax, cs
	mov ds, ax ;源地址ds:si 即do0的偏移地址,也就是中断处理程序
	mov si, offset do0  
	mov cx, offset do0end - offset do0 ;中断处理程序的字节数,也就是要转移的数量
	cld 
	rep movsb ;把中断处理程序安装至0000:0200
	mov ax, 0
	mov es, ax
;将中断例程的入口地址放置到中断向量表中
	mov word ptr es:[0 * 4], 200h ;将中断处理程序的入口放在0号中断向量中
	mov word ptr es:[0 * 4 + 2], 0

	mov ax, 4c00h
	int 21h

;中断处理程序
do0: ;为了防止字符串被覆盖所以将其放在中断例程里
	jmp short do0start
	db 'Divide overflow!', 0
do0start:
	mov ax, 0b800h  ;显存段地址
	mov es, ax
	mov di, 160 * 12 + 36 * 2 ;第13行中间位置
	mov ax, cs
	mov ds, ax
	mov si, 202h ;字符串的偏移地址
	mov cx, 10h ;字符串数目
s:
	mov bl, [si]
	mov es:[di], bl
	mov es:[di + 1], 2
	inc si
	add di, 2
	loop s
	iret  ;返回
do0end:
	nop
code ends
end start

以上是0号中断即除法溢出

下面说说1号中断即单步中断,单步中断与TF标志位密切相关,如果TF = 1代表开启单步中断,单步中断是什么?

举个例子用debug.exe程序用t指令观察指令执行时寄存器数值变化时,程序停了下来,原因就是单步中断

那么如果是这样有一个问题就是TF= 1那进入中断处理程序时不也会一直中断吗?即中断里面中断的循环,实际上这是不会的,因为:

取得终端类型码N->pushf->TF和IF置零(为了防止外中断和单步中断的产生)->push cs push ip->把cs设置成0000:[8 * 4],ip设置成0000:[8 * 4 + 2]即达到了中断例程的入口执行中断处理程序->使用iret返回

当单步中断产生时候即得到中断类型码1,把标志寄存器入栈后随即将TF置零,前面直到TF = 1时候单步中断才开启,这样进入单步中断处理程序后就不会再有中断产生了。


最后为何在设置ss:sp即栈段的时候中间不能够夹杂其他代码? 

mov ss, FC00h
int ? ;发生了某个中断
;取得终端类型码N->pushf->TF和IF置零(为了防止外中断和单步中断的产生)->push cs push ip
;所以改变了栈顶指针的位置使其指向错误位置
mov sp, 10h

这就是原因

(完)

接下去可看int中断: https://blog.csdn.net/qq_37232329/article/details/79895350







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值