第十二章 内中断

12.1 内中断的产生

发生情况:

  1. 除法错误(除法溢出时等)
  2. 单步执行
  3. 执行into指令
  4. 执行int指令

 

使用中断类型码的数据来标识中断信息的来源。

8086CPU中的中断类型码:

  1. 除法错误:0
  2. 单步执行:1
  3. 执行into指令:4
  4. 执行int指令

 

12.2 中断处理程序

 

12.3 中断向量表

定义:就是中断处理程序入口地址的列表

中断向量表存放着256个中断源所对应的中断处理程序的入口,8086CPU从0000:0000~0000:03FF存放向量表,且不可改变。一个表项,占两个字,高地址存放段地址,低地址存放偏移地址。

 

检测点 12.1

(1)70:018B

(2)4N,4N+2

 

12.4 中断过程

定义:CPU硬件通过中断类型码找到中断向量,并设置CS和IP的过程。

  1. 取得中断类型码
  2. pushf
  3. TF=0,IF=0
  4. push CS
  5. push IP
  6. (CS)=(4N+2), (IP)=(4N)

 

12.5 中断处理程序和iret指令

  1. 中断处理程序编写步骤:
  2. 保存用到的寄存器
  3. 处理中断
  4. 恢复用到的寄存器
  5. 用iret指令返回

iret返回:

pop IP

pop CS

popf

 

12.6 除法错误中断的处理

assume cs:code
code segment
start:
    mov ax,1000h
    mov bh,1
    div bh
code ends
end start

汇编学习--第十四天_中断向量

IF (interrupt flag)中断标志位由1变为了0

 

12.7 编程处理0号中断

 一般情况下,0000:0200h~0000:02FF的256个字节的空间中断向量表项都是空的,用来存储我们自己的程序。

 

12.8 安装

编译器可以处理表达式

 

12.9 do0

0号中断的处理程序:

  1. 将显示程序保存地址存储到0000:0200中
  2. 设置中断向量表:将0000:0200的段地址与偏移地址保存到0*4+2:0*4处
  3. 编写显示程序

 

12.10 设置中断向量

mov ax,0
mov es,ax
mov word ptr es:[0*4],0200h
mov word ptr es:[0*4+2],0

 

12.11 单步中断

CPU在执行完一段指令之后,如果检测到TF=1,则产生单步中断。

单步中断过程

  1. 取得中断类型码1
  2. 标志寄存器入栈,设置TF,IF为0--避免死循环中断
  3. CS,IP入栈
  4. (IP)=(1*4),(CS)=(1*4+2)

 

12.12 响应中断的处理情况

在执行设置ss和sp地址时,当执行到设置ss地址时,如果产生中断,则ss:sp并不是指向正确的栈顶地址,将产生错误。所以CPU在执行完,设置ss指令后,不产生中断,接着执行下一指令。因此我们正确的设置栈地址指令应为:

mov ax,stacksg
mov ss,ax
mov sp,10h

而不是

mov ax,stacksg
mov ss,ax
mov ax,0
mov sp,10h

 

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

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 word ptr es:[0*4+2],0
    mov word ptr es:[0*4],200h
    
    mov ax,4c00h
    int 21h
    
do0:
    jmp short do0start
    db 'Biu OverFlow!'
    
do0start:
    mov ax,0b800h
    mov es,ax
    mov ax,cs
    mov ds,ax
    mov si,202h
    mov di,12*160+36*2
    mov cx,13
s:
    mov al,ds:[si]
    mov es:[di],al
    mov byte ptr es:[di+1],4
    add di,2
    inc si
    loop s
    
    mov ax,4c00h
    int 21h
    
do0end:nop
    
code ends
end start

用了个测试程序

assume cs:code
code segment
start:
    int 0
code ends
end start

汇编学习--第十四天_中断向量_02

 

第十三章 int指令

13.1 int指令

int n相当于引发一个n号的中断处理程序,执行过程

  1. 取中断类型码
  2. 标志寄存器入栈,TF=0,IF=0
  3. CS,IP入栈
  4. (IP)=(4*n),(CS)=(4*n+2)

 

DOSBOX在调试的时候不会自动显示中断信息,而是跳到一个异常地址,所以我只能先把中断程序提前写入,再调用我们的程序。

assume cs:code
code segment
start:
    mov ax,0b800h
    mov es,ax
    mov byte ptr es:[13*160+40*2],'!'
    int 0
code ends
end start

汇编学习--第十四天_中断向量表_03

 

13.2 编写供应程序调用的中断例程

问题一:编写,安装中断7ch的中断例程

求一word型数据的平方

例如:2*2345^2

测试用例

assume cs:code
code segment
start:
    mov ax,2345
    int 7ch
    add ax,ax
    adc dx,dx
    
    mov ax,4c00h
    int 21h
code ends
end start

 

中断例程

assume cs:code
code segment
start:
   ;将程序转移到0000:0200 mov ax, cs mov ds,ax mov si,offset square mov ax,
0 mov es,ax mov di,200h mov cx,offset squareend-offset square cld rep movsb ;将程序中断程序入口地址写入中断向量表 mov ax,0 mov es,ax mov word ptr es:[7ch*4+2],0 mov word ptr es:[7ch*4],200h mov ax,4c00h int 21h square: mul ax iret;避免改变标记寄存器等和int组合使用 squareend:nop code ends end start

汇编学习--第十四天_寄存器_04

 

汇编学习--第十四天_中断向量_05