• 汇编内中断


    内中断


    1.内中断的产生

    任何一个通用的CPU,都具备一种能力,可以在执行完当前正在执行的指令之后,检测到从CPU外部发送过来的或内部产生的一种特殊信息,并且可以立即对所接收到的信息进行处理。这种特殊的信息,我们可以称其为:中断信息。中断的意思是指,CPU不再接着(刚执行完的指令)向下执行,而是转去处理这个特殊信息

    1. 中断信息可以来自CPU的内部和外部(内中断,外中断)
    2. 内中断:当CPU的内部有需要处理的事情发生的时候,将产生中断信息,引发中断过程。这种中断信息来自CPU的内部

    8086CPU的内中断(下面四种情况将产生中断信息):

    1. 除法错误,比如,执行div指令产生的除法溢出
    2. 单步执行
    3. 执行into指令
    4. 执行int指令

    中断信息中包含中断类型码,中断类型码为一个字节型数据,可以表示256种中断信息的来源(中断源)

    上述的4种内中断源,在8086CPU中的中断类型码如下:

    1. 除法错误:0
    2. 单步执行:1
    3. 执行into指令:4
    4. 执行int指令,该指令的格式为int n,指令中的n为字节型立即数,是提供给CPU的中断类型码

    2.中断处理程序、中断向量表、中断过程

    中断处理程序:

    1. 用来处理中断信息的程序被称为中断处理程序
    2. 根据CPU的设计,中断类型码的作用就是用来定位中断处理程序。比如CPU根据中断类型码4,就可以找到4号中断的处理程序

    中断向量表:

    1. 中断向量就是中断处理程序的入口地址。中断向量表就是中断处理程序入口地址的列表
    2. CPU用8位的中断类型码通过中断向量表找到相应的中断处理程序的入口地址

    请添加图片描述

    中断过程:

    1. 中断过程的主要任务就是用中断类型码在中断向量表中找到中断处理程序的入口地址,设置CS和IP
    2. 简要描述如下:
      1. 取得中断类型码N
      2. pushf
      3. TF=0,IF=0 (为什么这样参考单步中断)
      4. push CS , push IP
      5. (IP)=(N * 4),(CS)=(N * 4 + 2)
    3. 硬件在完成中断过程后,CS:IP将指向中断处理程序的入口,CPU开始执行中断处理程序

    3.iret指令

    CPU随时都可能执行中断处理程序,中断处理程序必须一直存储在内存某段空间之中,而中断处理程序的入口地址,即中断向量,必须存储在对应的中断向量表表项中

    中断处理程序的常规编写步骤:

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

    iret 指令描述为:pop IP pop CS popf

    iret指令执行后,CPU回到执行中断处理程序前的执行点继续执行程序


    4.除法错误中断的处理

    mov ax, 1000h 
    mov bh, 1
    div bh ;除法溢出错误
    
    • 1
    • 2
    • 3
    1. 当CPU执行div bh时,发生了除法溢出错误,产生0号中断信息,从而引发中断过程
    2. CPU执行0号中断处理程序
    3. 系统中的0号中断处理程序的功能:显示提示信息“Divide overflow”后,返回到操作系统中

    编程实验:编写0号中断处理程序do0,当发生除法溢出时,在屏幕中间显示“overflow!”,返回DOS

    实验要求:

    • 0000:0200至0000:02FF的256个字节的空间所对应的中断向量表项都是空的,可以将中断处理程序do0传送到内存0000:0200处
    • 中断处理程序do0放到0000:0200,再将其地址登记在中断向量表对应表项

    思路:

    • 0号表项的地址0:00:0字单元存放偏移地址,0:2字单元存放段地址
    • 将do0的段地址0存放在0000:0002字单元中,将偏移地址200H存放在0000:0000字单元
    assume cs:code
    
    code segment
    start:	
    		mov ax, cs
    		mov ds, ax
    		mov si, offset do0		;设置ds:si指向源地址
    		mov ax, 0
    		mov es, ax
    		mov di, 200h			;设置es:di指向目的地址0000:0200
    		mov cx, offset do0end - offset do0		;设置cx为传输长度 编译时给出do0部分代码长度
    		cld				        ;设置传输方向为正
    		rep movsb ;将do0的代码送入0:200处
    		
    		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程序的主要任务是显示字符串
    
    do0:	jmp short do0 start 
          	db "overflow!"
    
    do0start:
          	mov ax, cs
          	mov ds, ax
          	mov si, 202h			;设置ds:si指向字符串
    
          	mov ax, 0b800h
          	mov es, ax
    		mov di, 12*160+36*2		;设置es:di指向显存空间的中间位置
    
            mov cx, 9				;设置cx为字符串长度
    	s:	mov al, [si]
          	mov es:[di], al
          	inc si
          	add di, 1
    		mov al, 02h             ;设置颜色
    		mov es:[di], al        
    		add di, 1
          	loop s
    
          	mov ax, 4c00h
          	int 21h
    do0end:	nop
    
    code ends
    end start
    
    • 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

    5.单步中断

    1. CPU在执行完一条指令之后,如果检测到标志寄存器的TF位为1,则产生单步中断,引发中断过程。单步中断的中断类型码为1
    2. Debug是如何利用CPU所提供的单步中断的功能进行调试?如使用t命令查看寄存器状态
    3. Debug提供了单步中断的中断处理程序,功能为显示所有寄存器中的内容后等待输入命令
    4. 在使用t命令执行指令时,Debug将TF设置为1,在CPU执行完这条指令后就引发单步中断,执行单步中断的中断处理程序,所有寄存器中的内容被显示在屏幕上,并且等待输入命令
    5. 在进入中断处理程序之前,设置TF=0。从而避免CPU在执行中断处理程序的时候发生单步中断

    6.int指令

    1. int指令的格式为:int n ,n为中断类型码,它的功能是引发中断过程
    2. CPU执行int n指令,相当于引发一个n号中断的中断过程
    3. 在程序中使用int指令调用任何一个中断的中断处理程序(中断例程)

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

    //实验一
    ;2 * 3456^2
        
    assume cs:code
    
    code segment
    
    start: 
         mov ax, 3456 ;(ax)=3456
         int 7ch  ; 调用中断7ch的中断例程,计算ax中的数据的平方
         add ax, ax  
         adc dx, dx  ;存放结果,将结果乘以2
    
         mov ax,4c00h
         int 21h
    code ends
    end start 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    //实验二
    ;功能:将一个全是字母,以0结尾的字符串,转化为大写
    ;参数:ds:si指向字符串的首地址
    ;应用举例:将data段中的字符串转化为大写
        
    assume cs:code
    
    data segment
    	db 'conversation',0
    data ends
    
    code segment
    start:  mov ax, data
    		mov ds, ax
    		mov si, 0
    		int 7ch
    		
    		mov ax,4c00h
    		int 21h
    code ends
    end start   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    7.BIOS和DOS所提供的中断例程

    在系统板的ROM中存放着一套程序,称为BIOS(基本输入输出系统)

    BIOS中主要包含以下几部分内容:

    1. 硬件系统的检测和初始化程序
    2. 外部中断和内部中断的中断例程
    3. 用于对硬件设备进行I/O操作的中断例程
    4. 其他和硬件系统相关的中断例程

    程序员在编程的时候,可以用int指令直接调用BIOS和DOS系统提供的中断例程,来完成某些工作,和硬件设备相关的DOS中断例程中,一般都调用了BIOS的中断例程

    BIOS和DOS中断例程的安装过程:

    BIOS和DOS提供的中断例程是如何安装到内存中的呢?

    1. 开机后,CPU一加电,初始化(CS)= 0FFFFH,(IP)= 0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条转跳指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序
    2. 初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。注意,对于BIOS所提供的中断例程,只需将入口地址登记在中断向量表中即可,因为它们是固化到ROM中的程序,一直在内存中存在
    3. 硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交由操作系统控制
    4. DOS启动后,除完成其他工作外,还将它所提供的中断例程装入内存,并建立相应的中断向量

    BIOS中断例程应用:

    一般来说,一个供程序员调用的中断例程中往往包括多个子程序,中断例程内部用传递进来的参数来决定执行哪一个子程序

    BIOS和DOS提供的中断例程,都用 ah 来传递内部子程序的编号

    编程:在屏幕的5行12列显示3个红底高亮闪烁绿色的“al

    assume cs:code 
    
    code segment
    ;int 10h中断例程的"设置光标位置"功能
    mov ah, 2;设置光标调用第10h号中断例程的2号子程序,功能为设置光标位置(可以提供光标所在的行号、列号和页号作为参数)
    
    ;设置光标到第0页,第5行,第12列
    mov bh, 0;第0页
    mov dh, 5;dh中放行号
    mov dl, 12;dl中放列号
    int 10h
    
    ;int10h中断例程的"在光标位置显示字符"功能。
    mov ah,9 ;调用第10h号中断例程的9号子程序,功能为在光标位置显示字符
    ;提供要显示的字符、颜色属性、页号、字符重复个数作为参数
    mov al,'a'  ;字符
    mov b1,11001010b  ;颜色属性
    mov bh,0  ;0页
    mov cx,3  ;字符重复个数
    int 10h
    
    code ends 
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. bh中页号的含义:内存地址空间中,B8000H~BFFFFH共32kB的空间,为80*25彩色字符模式的显示缓冲区
    2. 一屏的内容在显示缓冲区中共占4000个字节。显示缓冲区分为8页,每页4KB(约4000B),显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。也就是说,通常情况下,B8000H~B8F9FH中的4000个字节的内容将出现在显示器上

    DOS中断例程应用:

    int 21h中断例程是DOS提供的中断例程,4ch号功能,即程序返回功能

    mov ah, 4ch ;调用第21h号中断例程的4ch号子程序,功能为程序返回,可以提供返回值作为参数
    mov al, 0 ;返回值
    int 21h
    
    • 1
    • 2
    • 3

    编程:在屏幕的5行12列显示字符串“Welcome to masm!”

    assume cs:code 
     
    data segment 
    	db	'Welcome to masm',  '$'     ;“$”本身并不显示,只起到边界的作用
    data ends 
    
    code segment
    start:	mov ah, 2 ;10号中断设置光标位置功能
    		mov bh, 0 ;0页
    		mov dh, 5;dh中放行号
    		mov dl, 12 ;dl中放列号
    		int 10h 
    		
    		mov ax, data 
    		mov ds, ax 
    		mov dx, 0 ;ds:dx指向字符串的首地址data:0  (参数)
    		mov ah, 9 ;调用第21h号中断例程的9号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数
    		int 21h 
    		
    		mov ax, 4c00h ;21号中断程序返回功能
    		int 21h 
    code ends
    end start
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    简单的咖啡文化静态HTML网页设计作品 DIV布局咖啡馆文化网页模板代码 DW咖啡网站制作成品
    MAX/MSP SDK学习05:A_GIMME方法
    http-server的安装、前端使用http-server启本地服务
    一次线上OOM问题的个人复盘
    Python pip 替换国内镜像源
    我为什么拒绝了一个5年测开经验的候选人
    高效访问数据的关键:解析MySQL主键自增长的运作机制!
    【深度学习】torchvision.transforms.Compose()
    谷粒商城--品牌管理(OSS、JSR303数据校验)
    【Kaggle项目实战记录】一个图片分类项目的步骤和思路分享——以树叶分类为例(用Pytorch)
  • 原文地址:https://blog.csdn.net/qq_29678157/article/details/127929436