马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 若余相思 于 2017-12-1 09:47 编辑
中断信息的含义:CPU在执行完当前正在执行的的指令之后,检测从CPU外部发来或内部产生的一种特殊的信息,
并且立即对所收到的信息进行处理
12.1节 中断的产生
当CPU有如下的情况发生时,将产生相应的中断信息
(1)除法错误
(2)单步执行
(3)执行into指令
(4)执行int指令
中断信息包含中断类型码,该码为一个字节数据类型,可以表述256种中断信息。比如除法错误的类型码是0
12.3节 中断向量表
中断必须要找到中断的地址来说设置CS和IP,然而去哪找呢?
中断向量表保存着256个中断源所对应的中断处理程序的入口地址
中断向量表存放在内存中,从0开始,从0000:0000到0000:03FF的1024个单元的中存放着中断向量表,不能存放在别处
中断处理程序的入口地址包括段地址和偏移地址,故一个表项中占两个字。高地址存放段地址,地址地存放偏移地址。
从而可以得知,存储N号中断源的中断处理程序入口的偏移地址为4N,段地址为4N + 2
12.4节 中断过程
中断在接收到中断的入口地址时,必须先保存原来的CS和IP以便恢复到原来的状态
中断的过程:
(1)取得中断类型码(从中断信息中获取)
(2)将标志寄存器的值入栈
(3)设置标志寄存器的第8位TF和第9位的IF的值位0
(4)CS入栈
(5)IP入栈
(6)将中断类型码N*4和N*4 + 2的两个字单元读取的中断处理程序入口地址设置为IP和CS
用更简洁的描述就是:
(1)取得中断类型码
(2)pushf
(3)TF = 0 和IF = 0
(4)push CS
(5)push ip
(6)(IP) = (N * 4) CS = (N * 4 + 2)
12.5节 中断处理程序和iret指令
由于CPU随时都要检测中断信息,所以中断处理程序必须一直存储在内存的某段空间中
中断处理程序的编写过程
(1)保存中断过程用到的寄存器
(2)处理中断
(3)恢复用到的寄存器
(4)用iret指令
iret指令用汇编描述为:
pop IP
pop CS
popf
由可以看出入栈时必须是先pushf,然后push CS,最后到IP
12.7节~12.10节 编程处理0号中断
按照书里面的套路就是:
(1)首先将中断的程序代码移动到0000:0200H处(利用movsv命令)
(2)然后将中断程序写出来(就是在屏幕显示字符的程序)
(3)注意将要显示的字符串放在0000:0200H处,这是因为数据段的信息会因为程序的结束而释放掉,然后被别的信息覆盖
但在0000:0200H的中断代码却一直保留着,因为中断是一直在监听的,当再次发生中断时,将显示字符串的不是你想要的信息。
故要将数据段的内容放在一段安全的地方
(4)最后就是修改中断向量表了
这里放上完成的代码(亲测可行哦)
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 ax, 0
mov es, ax
mov word ptr es:[0*4],200H
mov word ptr es:[0*4+2], 0
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+72
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
12.11节 单步中断
单步中断的类型码是:1
当TF标志位为1的时候将引发单步中断
debug每次执行完t时将显示寄存器的信息,利用的就是单步中断
为了不让单步中断陷入单步中断的死循环,每次单步中断之前都将TF为设置为0,我猜想其他中断也是要如此吧^_^
12.12节 响应中断的特殊情况
当执行压栈指令时将不引发中断过程,因为压栈过程是连续设置ss和sp的,这时引发中断将引发sp的不一致,从而导致错误
|