王爽 《汇编语言》 读书笔记 十二 内中断

来源:互联网 发布:淘宝客软文推广 编辑:程序博客网 时间:2024/05/29 09:00

第十二章 内中断


中断:cpu能接收到内部或外部的某种信息,cpu不再接着向下执行,而是转取处理这个特殊信息。


12.1 内中断的产生

cpu内部有下面情况发生将产生相应的中断信息。

1)除法错误,比如,执行div指令产生的除法溢出  (中断码 0)

2)单步执行 (1)

3)执行into指令 (4)

4)执行int指令 (int n)

cpu通过中断类型码来识别中断的来源。


12.2 中断处理程序

cpu收到中断信息后,需要中断信息处理程序。 对不同的中断信息编写不同的处理程序。根据中断类型码和中断向量表来定位中断处理程序


12.3 中断向量表

一张存放中断处理程序入口地址的列表。 中断向量表存放于内存中,其中放着256个中断源所对应的中断处理程序的入口


8086cpu默认的中断向量表存放于 0000:0000 ~ 0000:03FF

一个表项占用2个字(4个字节),高地址存放段地址,低地址存放偏移地址。 


12.4 中断过程

cpu收到内部或外部中断以后会根据中断码寻找中断向量表中的中断处理程序的入口地址,并设置CS 和IP。 称为中断过程

以下是8086执行中断的过程:

1) 取得中断类型码:

2)标志寄存器的值入栈(pushf)

3)设置标志寄存器的第八位TF和第九位IF为0  TF=0, IF=0

4)CS的内容入栈 push CS

5)IP的内容入栈 push IP

6)从内存地址为中断码x4 和中断码x4+2 的两个字单元读取中断处理程序的入口地址并设置IP和CS    IP = (N * 4)  CS = (N*4 + 2)


12.5 中断处理程序和iret指令

1) 保存用到的寄存器

2)处理中断

3)恢复用到的寄存器

4)用iret指令返回


POP IP

POP CS

POPf


12.6 除法错误中断处理程序

屏幕上输出

Divide overflow

12.7 编程处理0号中断

编程:当发生除法溢出的时候,产生0号中断信息,从而引发中断过程。

0000:0000~0000:03FF 都是中断向量表。 但是为了脱离操作系统。这里使用0000:0200~0000:02ff的256个字节存放自己的程序。

1)编写可以显示“overflow!”的中断处理程序:do0:

2)将do0送入内存0000:0200处

3)将do0的入口地址0000:0200 存储在中断向量表的0号表项中


12.8  安装

assume cs:codecode segmentstart:; set es:di as target address 0000:0200hmov ax, 0mov es, axmov di, 200h; set ds:si as source address cs:do0mov ax, csmov ds, axmov si, offset do0; set cx as the data lengthmov cx, offset do0end - offset do0; set the transport directive DF = 0 cldcldrep movsb; set the IRQ tablemov ax, 0mov es, axmov word ptr es:[0 * 4], 200hmov word ptr es:[0 * 4 + 2], 0mov ax, 4c00hint 21hdo0:jmp short do0startdb "overflow!"; show the string "Overflow!"do0start:mov ax, csmov ds, ax; set ds:si to the string buffermov si, 202h; the string will be move to 202hmov ax, 0b800hmov es, axmov di, 12 * 160 + 36 * 2; point to the center of the screenmov cx, 9s:mov al, [si]mov es:[di], alinc siadd di, 2loop smov ax, 4c00hint 21hdo0end:nopcode endsend start

运行结果


12.11 单步中断

cpu中执行完一条指令后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。执行过程如下

1)取得中断类型码1

2)标志寄存器入栈,TF IF设为0

3)CS, IP入栈

4)(IP) = (1*4)   (CS) = ( 1*4 + 2)


Debug在执行t指令时,将tf设为1,使得cpu工作于单步中断的方式下,在cpu执行完这条指令以后就会引发单步中断,执行单步中断的中断处理程序,所有寄存器中的内容被显示在屏幕上,并等待输入命令。

为了防止cpu处理单步中断陷入死循环,在进入单步中断处理程序之前TF会被设置为0.

为了单步跟踪程序的执行过程,提供了实现机制。


12.12 响应中断的特殊情况


在执行完向ss寄存器传送数据的指令后,即便是发生中断cpu也不会响应。因为ss:sp联合指向栈顶,对他们的设置应该连续完成。如果设置完ss以后cpu响应中断,要在栈中压入标志寄存器,cs和ip的值。(而此后sp会被改变)此时的栈顶是不正确的。所以cpu在执行设置完ss以后不响应中断。


实验 编写0号中断处理程序


assume cs:codecode segmentstart:; set es:di as target address 0000:0200hmov ax, 0mov es, axmov di, 200h; set ds:si as source address cs:do0mov ax, csmov ds, axmov si, offset do0; set cx as the data lengthmov cx, offset do0end - offset do0; set the transport directive DF = 0 cldcldrep movsb; set the IRQ tablemov ax, 0mov es, axmov word ptr es:[0 * 4], 200hmov word ptr es:[0 * 4 + 2], 0mov ax, 4c00hint 21hdo0:jmp short do0startdb "divide error!", 0; show the string "Overflow!"do0start:mov ax, csmov ds, ax; set ds:si to the string buffermov si, 202h; the string will be move to 202hmov ax, 0b800hmov es, axmov di, 12 * 160 + 36 * 2; point to the center of the screens:mov al, [si]cmp al, 0je exitmov es:[di], alinc siadd di, 2loop sexit:mov ax, 4c00hint 21hdo0end:nopcode endsend start