汇编语言(王爽)-第十二章

第十二章 内中断
*四种引发内中断的情况
(1)除法错误,如溢出;对应中断类型码0
(2)单步执行;对应中断类型码1
(3)into指令;对应中断类型码4
(4)int N;对应中断类型码N
*中断向量表
当引发内中断时候,cpu转入执行相应中断程序,而各类中断类型码对应的中断程序固化存于内存中;这就需要通过不同的中断类型码以获取其对应的
中断程序的入口地址,即有了中断向量表。
中断向量表固化于0000:0000~03ffh内存段中;
中断类型码n:对应中断程序的入口地址为:段地址0000:(4n+2),偏移地址0000:(4n).
*中断过程
-----中断开始------
(1)响应中断,取得中断类型码n
(2)pushf
(3)TF=0,IF=0
(4)push cs,push ip
(5)cs=(0000:(4n+2)),ip=(0000:(4n));
(6)执行中断程序
(7)iret 返回<iret指令实际是在中断程序中的>
-------中断结束----------
*中断程序的编写、安装
(1)编写中断程序X
(2)安装中断程序X(一般来说,小型中断程序可放于0000:200~2ffh中,该段是空闲的)
(3)修改中断向量表,使中断类型码对应该中断程序入口
程序框架:
assume cs:codesg
codesg segment
  start: 安装X的代码
           设置中断向量表
           mov ax,4c00h
           int 21h
       X:
            ....
            mov ax,4c00h
            int 21h
      Xend:
            nop           ;空执行语句,以便计算X的代码长度确定安装空间即loop次数
codesg ends
end start
?1、不难发现,上述程序框架中X代码中返回的指令用的是mov ax,4c00h/int 21h;而之前提过需要用iret来进行返回。这里是怎么回事呢?细想一下:其实两个返回是需要根据情况来使用的,对于除法溢出,其返回的目标是dos,所以需要用mov ax,4c00h/int 21h,而其他一些返回的目标是触发中断的原程序,则需要用iret。
?2、关于书中所提对于除法溢出中断处理程序用到的字符串"overflow!'的存储。书中采用的方法是:
do0:jmp short do0start
       db "overflow!"
do0start:
        .....
         mov ax,4c00h
         int 21h
do0end:nop
这样的话,字符串overflow!被固化在内存中,就不会被改变了。而jmp short do0start这句的作用是使ip跳转至中断程序的实际上的第一句,书上的解释是"overflow!"并不是可执行的代码。而我个人的看法,更合适的解释是,如果没有jmp语句,顺序执行到'overflow!'处会将其看成指令,从而产生错误。
*单步中断
单步中断的类型码为1,其触发的条件是单步中断标志位TF=1;即:
若探测到TF=1,则触发单步中断,类型码为1,转而执行单步中断处理程序,执行其第一个语句;再次探测到TF=1,从而产生无限循环。这也就是为什么在中断处理过程中在pushf后需要将TF设置为0的原因。
*响应中断的特殊情况
在对栈寄存器ss赋值后,即便产生中断,也不会响应,而是继续设置完成sp栈顶值。
假设SS赋值后,响应中断,则取得中断类型码,pushf,TF=IF=0,push cs,push ip...此时这些push操作所用的栈的段地址为ss,而sp呢?未设置,则不是期待中的位置,可能会引起错误。所以对ss和sp的赋值是必须连续的。

原文地址:https://www.cnblogs.com/tsembrace/p/3305646.html