中断向量表

8086系统在存储器的最低1KB区域(00000H~003FFH)建立一个中断向量表,存放256个中断类型的中断向量。这1024个单元被分成256组,每组包括4个字节单元,存储一个中断向量的段基址和段内偏移地址,高2个字节用於存放段基址,低两个字节用於存放段内偏移地址。

8086系统把中断向量表中的中断明确分为3个部份:
1.专用中断:类型号0~4(所以中断不是从1开始,而是0)
2.系统备用中断:类型号5~31H
3.用户中断:类型号32H~0FFH

##检测点12.1分析:
0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
问3号对应的 处理程序入口

计算中断服务入口地址的方法是:

从内存地址为中断类型码*4和中断类型码*4+2的两个字单元中读取中断处理过程的入口地址设置IP和CS

0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
段基址:偏移地址 0 1 2 3 4 5 6 7 8 - 9 10 11 12 13 14 15(16个bytes,“-”为分隔符,每8个bytes分隔一次)
0号:00A7:1068
1号:0070:108B
2号:039D:0016
3号:0070:108B

3号:IP读取34=12的两个bytes就是12和13两个bytes,CS读取34+2=14的两个bytes就是14和15两个bytes。

中断过程

内中断,cpu什么时候会发出中断信号呢?一般有一下四种情况:

·除法指令

·单步执行

·int 0指令

·int n指令

产生中断信号的情况又被称为中断源。cpu接收到中断信号以后,要根据中断信号来确定中断情况。所以,中断信息里面应该包括中断的来源以及中断的情况。因此,CPU将定义一个变量来存储辨别中断信息,称为中断字节码(8位变量)可以用中断字节码表示256种情况。

每种中断情况都对应一种中断处理程序,但是CPU又如何确定相应中断处理程序在内存中的地址呢?如何确定相应中断处理程序的入口地址?so,中断向量应运而生。中断向量就是中断处理程序的入口地址。不同的中断情况对应不同的中断处理程序,又对应不同的中断向量,为了高效的处理中断,我们又定义了中断向量表,顾名思义,中断向量表用来存储中断向量,就是中断处理程序的入口地址。一条中断向量有占用多少内存地址呢?中断向量用来存储中断处理程序的入口地址,包括段地址和偏移地址,所以占用两个字的存储单元,高地址字段用来存储段地址,低地址字段用来存储偏移地址。

CPU知道了相应中断处理程序的入口地址后,计算机处理中断,中断过程。用中断字节码找到中断向量,来设置CS和IP,这个过程由计算机硬件来完成,这个过程叫做中断过程。 以8086CPU为例,在接收到中断信息后,要执行的操作:

  1.(从中断信息中)找到中断字节码

  2.标志寄存器的值入堆栈

  3.设置标志寄存器的第8位TF和第9位IF值为0
  4.CS 值入栈
  5.IP值入栈
  6.从内存地址为 终端类型码4 和 中断类型码4+2的两个字单元读取中断处理程序的入口地址,设置CS IP

中断处理程序
  由于cpu随时都有可能检测到中断信息,也就是说cpu随时都要执行中断处理程序,所以,中断处理程序必须一致存储在内存某段空间中。
  中断处理程序的步骤:

  1.保存用到的寄存器
  2.处理中断
  3.恢复用到的寄存器
  4.用iret指令返回

cpu执行完中断处理程序以后,必须返回到原来的地址继续执行后面的内容,所以,在执行中断处理程序之前必须记录下原来执行指令的地址,便于中断处理完以后返回。

实验12

编写0号中断处理程序,在发生除法溢出时,在屏幕中间显示字符串  xxxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
assume cs:code

code segment

start:
mov ax,cs
mov ds,ax
mov si,offset do0 ; 设置ds指向被复制代码

mov ax,0
mov es,ax
mov di,0200h ; 设置es指向要复制到的区域 CS:IP 0000:0200

mov cx,offset do0done-offset do0 ; 设置被复制的代码长度
; 右边的计算是由编译器来完成的
cld ; 正向复制
rep movsb ; 复制

mov ax,0
mov es,ax ; 指向 0:0
mov word ptr es:[0*4],0200h
mov word ptr es:[0*4+2],0
; 修改中断向量表
; 写入地址, N号中断对应的内存地址为4N+2
; 偏移为4N
mov ax,1000h
mov bh,1
div bh ; 产生溢出错误

mov ax,4c00h
int 21h


do0:
jmp short do0start ; 跳转到程序运行的地方,否则CS:IP指向字符串将不能运行
db "0V3rFlow!!"
do0start:
mov ax,cs
mov ds,ax
mov si,0202h ; 设置ds:si 指向字符串

mov ax,0b800h ; 显存地址
mov es,ax
mov di,12*160+36*2 ; 指向显存中间位置

mov cx,10 ; 设置字符串长度
display:
mov al,[si]
mov es:[di],al ; 只设置低位字符 (一个字节,8bit)
mov byte ptr es:[di+1],61h ; 设置高位属性 (一个字节,8bit)
inc si
add di,2
loop display

cld ; 正向复制
rep movsb ; ds 复制到 es

mov ax,4c00h
int 21h
do0done:
nop

code ends
end start

联想: 溢出攻击,修改中断处理程序,使程序产生中断(例如溢出中断处理),来达到调用我们编写的恶意程序