• 汇编语言外中断


    外中断


    1.外中断概念

    1. CPU在计算机系统中,除了能够执行指令,进行运算以外,还应该能够对外部设备进行控制,接收它们的输入,向它们进行输出(I/O能力)
    2. PC系统的接口卡和主板上,装有各种接口芯片。这些外设接口芯片的内部有若干寄存器,CPU将这些寄存器当作端口来访问
    3. 外设的输入不直接送入内存和CPU,而是送入相关的接口芯片的端口中
    4. CPU向外设的输出也不是直接送入外设,而是先送入端口中,再由相关的芯片送到外设
    5. CPU还可以向外设输出控制命令,而这些控制命令也是先送到相关芯片的端口中,然后再由相关的芯片根据命令对外设实施控制,即:CPU通过端口和外部设备进行联系
    6. 当CPU外部有需要处理的事情发生的时候,比如说,外设的输入到达,相关芯片将向CPU发出相应的中断信息。CPU在执行完当前指令后,可以检测到发送过来的中断信息,引发中断过程,处理外设的输入

    PC系统中,外中断源有两类:

    1. 可屏蔽中断
      1. 可屏蔽中断是CPU可以不响应的外中断。CPU是否响应可屏蔽中断,要看标志寄存器的IF位的设置
      2. 当CPU检测到可屏蔽中断信息时,如果IF=1,则CPU在执行完当前指令后响应中断,引发中断过程;如果IF=0,则不响应可屏蔽中断
      3. 可屏蔽中断信息来自于CPU外部,中断类型码是通过数据总线送入CPU的;而内中断的中断类型码是在CPU内部产生的
      4. 中断过程中将IF置0的原因就是,在进入中断处理程序后,禁止其他的可屏蔽中断
      5. 如果在中断处理程序中需要处理可屏蔽中断,可以用指令将IF置1
      6. 8086CPU提供的设置IF的指令:sti,设置IF=1;cli,设置IF=0
    2. 不可屏蔽中断
      1. 不可屏蔽中断是CPU必须响应的外中断。当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程
      2. 对于8086CPU,不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要取中断类型码。则不可屏蔽中断的中断过程为:①标志寄存器入栈,IF=0,TF=0;②CS、IP入栈;③(IP)=(8),(CS)=(0AH)
      3. 几乎所有由外设引发的外中断,都是可屏蔽中断。当外设有需要处理的事件(比如说键盘输入)发生时,相关芯片向CPU发出可屏蔽中断信息。不可屏蔽中断是在系统中有必须处理的紧急情况发生时用来通知CPU的中断信息

    2.PC机键盘的处理过程

    1. 键盘中有一个芯片对键盘上的每一个键的开关状态进行扫描。按下一个键时,开关接通,该芯片就产生一个扫描码,扫描码说明了按下的键在键盘上的位置。扫描码被送入主板上的相关接口芯片的寄存器中,该寄存器的端口地址为60h。松开按下的键时,也产生一个扫描码,扫描码说明了松开的键在键盘上的位置。松开按键时产生的扫描码也被送入60h端口中
    2. 一般将按下一个键时产生的扫描码称为通码,松开一个键产生的扫描码称为断码
    3. 扫描码长度为一个字节,通码的第7位为0,断码的第7位为1。即:断码 = 通码 + 80h。比如,g键的通码为22h,断码为a2h
    4. 键盘的输入到达60h端口时,相关的芯片就会向CPU发出中断类型码为9的可屏蔽中断信息。CPU检测到该中断信息后,如果IF=1,则响应中断,引发中断过程,转去执行int 9中断例程

    请添加图片描述

    BIOS提供了int 9中断例程,用来进行基本的键盘输入处理,主要的工作如下:

    1. 读出60h端口中的扫描码
    2. 如果是字符键的扫描码,将该扫描码和它所对应的字符码(即ASCII码)送入内存中的BIOS键盘缓冲区; 如果是控制键(比如Ctrl)和切换键(比如CapsLock)的扫描码,则将其转变为状态字节写入内存中存储状态字节的单元
    3. 对键盘系统进行相关的控制,比如说,向相关芯片发出应答信息

    BIOS键盘缓冲区可以存储15个键盘输入,一个键盘输入用一个字单元存放,高位字节存放扫描码,低位字节存放字符码

    0040:17单元存储键盘状态字节,该字节记录了控制键和切换键的状态。键盘状态字节各位记录的信息如下:

    请添加图片描述

    编写int 9中断例程:

    ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。在显示的过程中,按下'Esc'键后,改变显示的颜色。
    
    ;完整功能代码:
    ;---------------------int 9中断例程---------------------------
    assume cs:code
    
    stack segment
    	db 128 dup (0)
    stack ends
    
    data segment
    	dw 0,0
    data ends
    
    code segment
    start:	
    	mov ax,stack
    	mov ss,ax
    	mov sp,128
    	mov ax,data
    	mov ds,ax
    	mov ax,0
    	mov es,ax
    
    	push es:[9*4]
    	pop ds:[0]
    	push es:[9*4+2]
    	pop ds:[2]		;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中
    
    	mov word ptr es:[9*4], offset int9
    	mov es:[9*4+2], cs	;在中断向量表中设置新的int 9中断例程的入口地址
    
    ;显示字符串
    	mov ax, 0b800h
    	mov es, ax
    	mov ah, 'a'
    s:	
    	mov  es:[160*12+40*2], ah
    	call delay
    	inc ah
    	cmp ah, 'z'
    	jna s
    	mov ax,0
    	mov es,ax
    
    	push ds:[0]
    	pop es:[9*4]
    	push ds;[2]
    	pop es;[9*4+2]   	;将中断向量表中int 9中断例程的入口恢复为原来的地址
    
    	mov ax,4c00h
    	int 21h
    
    ;将循环延时的程序段写为一个子程序
    delay:	
    	push ax 
    	push dx
    	mov dx, 2000h  ;用两个16位寄存器来存放32位的循环次数
    	mov ax, 0
    s1: 	
    	sub ax, 1
    	sbb dx, 0
    	cmp ax, 0
    	jne s1
    	cmp dx, 0
    	jne s1
    	pop dx
    	pop ax
    	ret
    
    ;------以下为新的int 9中断例程--------------------
    
    int9:	
    	push ax
    	push bx
    	push es
    
    	in al, 60h;从端口60h读出键盘的输入
    
    	pushf ;标志寄存器入栈
    
    	pushf   
    	pop bx
    	and bh,11111100b
    	push bx
    	popf	;TF=0,IF=0
    	
    	call dword ptr ds:[0] 	;int指令进行模拟,调用原来的int 9中断例程
    
    	cmp al,1
    	jne int9ret
    
    	mov ax,0b800h
    	mov es,ax
    	inc byte ptr es:[160*12+40*2+1]  ;属性增加1,改变颜色
    
    int9ret:
    	pop es
    	pop bx
    	pop ax
    	iret
    
    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
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105

    CPU对外设输入的通常处理方法:
    (1)外设的输入送入端口
    (2)向CPU发出外中断(可屏蔽中断)信息
    (3)CPU检测到可屏蔽中断信息,如果IF=1,CPU在执行完当前指令后响应中断,执行相应的中断例程
    (4)可在中断例程中实现对外设输入的处理

  • 相关阅读:
    SQL Server 入门知识
    Java8 Lambda.stream.sorted() 方法使用浅析分享
    【网络安全】内网杀器之Cobalt Strike
    2024050401-重学 Java 设计模式《实战代理模式》
    【Python编程】八、Python函数详解
    html网页设计与制作:基于html设计整套招聘网站求职前端模板页面 静态网页HTML代码 学生网页课程设计期末作业下载
    苍穹外卖-01
    token详细介绍及实现登录
    【编程题】【Scratch三级】2021.03 加法出题机
    构建“产业大脑”,以“数字化”提升园区运营管理及服务能力!
  • 原文地址:https://blog.csdn.net/qq_29678157/article/details/127929494