什么是中断?

中断是bios(basic input/output system)程序内置的一套cpu调度事件的的程序(个人理解)它需要符合各类硬件厂商的标准,比如你想从硬盘读一些数据到内存,那么你需要调用13号中断。但是标准化的今天,这些厂商遵循了一定的规范和标准,所以能够进行各种适配。
中断程序和call指令调用过程类似。我们甚至可以修改中断程序。

什么是中断向量表?

词听起来很高大上,实际上就是一张表格存着我的程序在内存中的哪个位置,即当我调用int 0的时候,我从内存0:0位置取到4个字节,将高位给cs,将低位给ip,改变程序指令指针寄存器,让cpu跳转到对应位置去执行代码。

中断的的调用过程如下

1、取中断类型码N 2、标志位寄存器入栈 pushf 3、置为中断标志位与调试标志位。TF=0,IF=0 4、push cs push ip 5、cs=N*4+2 ip=N*4 6、调用中断程序
7、iret 出栈返回
相当于执行 call dword ptr 我们先来看看中断0,程序如下

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    int 0
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

我们开始调试 直接g 5 我们观察cs=0770 ip=0005

MBR调用BIOS中断_MBR调用BIOS中断


在单步t 我们发现cs=F000 ip=1060 那么这两个值从哪里来呢?我们查看数据d 0:0的位置

MBR调用BIOS中断_数据段_02


d 0:0 我们发现正好是f000:1060,而0:0位置就是内存最开始的位置

MBR调用BIOS中断_8086_03


我们持续按d命令查看相关内存发现当数据到01e0之后就没有数据。也就是这里存了一张表,这张表是以4个字节位单位的。并且大小1d4为止。实际上人家规定了从内存的0~3FF为中断向量表,一共1024个字节,但是实际只用到了468个字节每4个字节表示一个中断,也就是在dos下中断向量表有117个中断。

MBR调用BIOS中断_数据_04


我们直接运行程序结果如下0号中断代表除法错误

MBR调用BIOS中断_数据段_05


对应的表格我就不贴了,用到自己百度去吧

我们再来看另一段程序
栈的设置

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    dw 8 dup(0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    mov ax,stacks
    mov ss,ax
    mov sp,16
    push ax
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START
    MOV DS,AX
    mov ax,stacks
    mov ss,ax
    mov sp,0
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

我们单步按t执行,我们发现 mov sp,16这行代码被跳过了,为什么呢?因为这里面发生了中断,将TF标志置为0,而TF标志表示是否允许调试为0则不允许,所以就t指令不产生作用。

MBR调用BIOS中断_数据_06


我们在看执行push ax指令前后栈中的数据,我们发现执行前栈中数据全为0,而执行后发现栈中多了好多数据,我们明明就push 了一个0770 为什么前面会多出那么多数据呢?

我们来看看01a6 = 0000 0001 1010 0110 在此之前我们了解下标志位对照表

15 14 13 12 11  10 09  08  07 06 05 04 03 02 01 00
            OF  DF IF  TF  SF ZF    AF    PF    CF

我们在来看看对应标志位的数据

OF=NV(0) OV(1)

DF=UP(0) DN(1)

IF=EI(1) DI(0)

SF=PL(0) NG(1)

ZF=NZ(0) ZR(1)

AF=NA(0) AC(1)

PF=PO(0) PE(1)

CF=NC(0) CY(1)

我们发现和我们以上0000 0001 1010 0110 并不对应,这个是个疑惑,这里应该是push指令里面做了什么事情该表了相关的位。

而第二个位置的值位0771,对应cs,第三个位置的值000d对应ip这个没错,栈顶指向了我们push进去的ax也没错。

也就是T指令产生了调试中断。

也就是执行了上面所说的几个指令pushf push cs push ip。但是我们用了t指令所以 TF=1 实际栈中的值没有错

这个我也不知道该如何验证。

MBR调用BIOS中断_中断向量表_07