20、中断和动态时钟显示


上一节:19、硬盘和显卡的访问与控制
下一节:21、32位x86处理器编程架构

01、中断和硬件中断

非屏蔽中断NMI、可屏蔽中断INTR
在这里插入图片描述

02、中断控制器简介

使用8259A中断控制器芯片,其有自己的端口号,可以设置中断的优先级、屏蔽某些中断信号等等,中断引脚的优先级从高到低依次为主片IR0~~IR1、从片IR0~~IR7、主片的IR3~~IR7
在这里插入图片描述
8259A内部有一个中断屏蔽寄存器,对应引脚输入0表示允许中断进入、1表示禁止中断进入。
在这里插入图片描述
除了中断屏蔽寄存器,还有处理器内部的FLAGS标志寄存器中的IF标志位:IF0表示忽略中断信号、IF1表示接收中断信号,使用CLISTI设置标志位IF
在这里插入图片描述

03、中断号、中断处理过程、中断向量表

默认中断号为:
在这里插入图片描述
中断处理过程:在实模式下,保护现场,处理器知道了中断号,使用中断号访问中断向量表,从中取出中断处理程序的逻辑段地址和偏移地址,转到那里去执行中断处理程序,执行完之后返回。
在这里插入图片描述
中断向量表IVT:是BIOS在开机时创建。
在这里插入图片描述
使用Bochs虚拟机调式:中断向量表1000个字节,512个字,从地址0开始。
设置断点:b 0x7c00
查看IVTxp /512xh 0
在这里插入图片描述

04、实时时钟、CMOS RAM和BCD编码

实时时钟:提供基准时间,存储在CMOS RAM芯片中。
CMOS RAM64~256字节之间,日期和时间信息占据一小部分,剩余的用来保存整机的配置信息(硬件类型、工作参数、开机密码、辅助存储设备的启动顺序等等)。
在这里插入图片描述
索引端口0x700x74,指定偏移地址(索引号);
数据端口0x710x75,用来读取偏移地址处的内容。

二进制形式的十进制编码(BCD:Binary Coded Decimal
左边25的十进制,右边上为纯二进制编码,右边下为BCD编码。
在这里插入图片描述

05、实时时钟芯片的中断信号

RTC可产生3种中断信号:
在这里插入图片描述
1、PF(Periodic Interrupt)
可调节,最慢500ms发生一次、最快30.517us发生一次,使用下图修改。
在这里插入图片描述
分频器修改:这是基于32.768KHz时的设置。
在这里插入图片描述
其他频率参考MC146818芯片手册。
在这里插入图片描述
PF中断是否允许发生由寄存器B位6控制,0为不允许、1为允许。
在这里插入图片描述
若寄存器A位3~0选择了0000,则寄存器B的位6自动置0

2、UI(Update-ended Interrupt)
每隔一秒,RTC将更新CMOS RAM中的时间和日期,更新操作包括读取并增加日期和时间、检查数据是否超出范围并溢出、检查是否到了闹钟时间,设置相关寄存器的状态,最后更新之后的数据写回原来的位置。

这些步骤和过程叫做更新周期,在每个更新周期结束时,若允许,RTC将发出一个中断信号表示本次周期更新结束,就叫做更新周期结束中断。

更新周期时候会进行由寄存器B的位7控制:为0表示每秒都会产生、为1表示暂停更新周期并且此后不再产生更新周期。

更新周期结束中断时候产生取决于寄存器B的位4:为0表示不产生、为1比爱是允许在每个更新周期结束时产生中断。
在这里插入图片描述
更新周期是否开始由寄存器A的位7决定:此位是只读的,为0表示更新周期至少在488us内不会启动,即此时访问CMOS RAM中的时间是安全的;为1表示正处于更新周期,或者更新周期马上就要启动。

如果寄存器B的位7(SET位)为0,在分频电路正确配置的情况下,更新周期每秒发生一次,更新周期至少在寄存器B的位7(UIP位)置1之后的488us内开始,而且整个周期的完成时间不会多余1984us。

在更新周期进行的时候,和日期时间有关的存储单元0x00~0x09的这一部分会和外部总线脱离,为了防止因外部数据访问导致的数据冲突和破坏;
因此要安全的访问0x00~0x09这一部分数据,要避开更新周期,有两个可以选择的时机:

  • 1、当检测到更新结束中断发生时,有999ms时间用于读取有效的日期时间和数据。
  • 2、若检测到寄存器A的位7(UIP位)是0,意味着在更新周期开始之前滑油488us的时间用于读取有效的日期时间和数据。

在这里插入图片描述

3、AI(Alarm Interrupt)
寄存器B的位5(AIE位)控制闹钟中断信号是否会产生:为0表示不产生、为1表示产生。
在这里插入图片描述
中断类型的判断:读取寄存器C相关位进行判断。
在这里插入图片描述

  • 位7:为1表示有中断发生、为0表示没有;
  • 位7为1时再根据位4、5、6进一步判断是哪种中断发生;
  • 位6:为0表示没发生、为1表示发生;
  • 位5:为0表示没发生、为1表示发生;
  • 位4:为0表示没发生、为1表示发生;
  • 其中低4位始终保持为0,寄存器C是只读的,读操作将会导致所有位被清零

06、安装0x70号中断的处理过程

加载器程序使用c08_mbr.asm,加载器是一样的可通用,具体代码查看c09_1.asm

当处理器执行任何一条改变栈段寄存器SS的指令时,会在下一条指令执行前禁止中断,所以修改SP的指令需要紧跟在修改SS的指令后面。

访问中断向量表:因为IVT保存在物理地址为0处,所以程序中将地址0x0000当作段地址传给ES
在这里插入图片描述

07、启用更新周期结束中断

此小节代码如下,具体代码查看c09_1.asm

...
	cli								;防止改动期间发生新的0x70号中断
	
	push es
	mov ax,0x0000
	mov es,ax
	mov word [es:bx],new_int_0x70	;偏移地址。
	
	mov word [es:bx+2],cs			;段地址
	pop es
	
	mov al,0x0b						;RTC寄存器B
	or al,0x80                      ;阻断NMI 
	out 0x70,al
	mov al,0x12                     ;设置寄存器B,禁止周期性中断,开放更 
	out 0x71,al                     ;新结束后中断,BCD码,24小时制 
	
	mov al,0x0c
	out 0x70,al						;如果不清零,相应中断将不再产生
	in al,0x71                      ;读RTC寄存器C,复位未决的中断状态
									;没有屏蔽最高位的中断允许位,因为这是
									;最后一次设置RTC,利用这个机会打开非屏蔽中断NMI
	
	in al,0xa1                      ;读端口0xA1(默认)读8259从片的IMR寄存器 
	and al,0xfe                     ;清除bit 0(此位连接RTC)
	out 0xa1,al                     ;写回此寄存器 
	
	sti                             ;重新开放中断 
...

阻断NMI信号原理:
在这里插入图片描述
寄存器B的各个位介含义:
在这里插入图片描述
代码中设置寄存器B的值为0x12,含义参考上图即可。

其中小时模式为12小时制时,其中时所在寄存器位7位0表示上午、为1表示下午。
在这里插入图片描述
8259从片的IMR寄存器,来设置中断屏蔽寄存器的相应位为0已开启以开启中断。
在这里插入图片描述

08、用TEST指令等待更新周期结束

此小节代码如下,具体代码查看c09_1.asm

...
	.w0:                                    
	mov al,0x0a		;阻断NMI。当然,通常是不必要的
	or al,0x80                          
	out 0x70,al
	in al,0x71		;读寄存器A
	test al,0x80	;测试第7位UIP 
	jnz .w0 		;以上代码对于更新周期结束中断来说 
					;是不必要的 
....

判断RTC是否处于更新周期,根据寄存器A的位7判断:0表示未开始,此时访问CMOS RAM中的日期时间是安全的、1表示正处于更新周期或者更新周期马上就要启动。
在这里插入图片描述
使用test指令判断某一位是0还是1,test指令的and指令类似,但是test指令执行之后不保存运算结果,影响标志位ZFSFPFAF未定义,OF=CF=0
在这里插入图片描述
RTC更新周期时序:
在这里插入图片描述

09、读取BCD码的时间并显示在屏幕上

此小节代码如下,具体代码查看c09_1.asm

...
      mov ax,0xb800
      mov es,ax

      pop ax
      call bcd_to_ascii
      mov bx,12*160 + 36*2               ;从屏幕上的12行36列开始显示
										 ;一个字符占2个字节
      mov [es:bx],ah
      mov [es:bx+2],al                   ;显示两位小时数字
....

时间的时分秒分别在CMOS RAM0、2、4位上:
在这里插入图片描述

10、用NOT指令反转时间分隔符的颜色

此小节代码如下,具体代码查看c09_1.asm

...
	mov al,':'
	mov [es:bx+4],al		;显示分隔符':'	mov byte [es:bx+4], ':'
	not byte [es:bx+5]		;反转显示属性 
	
	pop ax
	call bcd_to_ascii
	mov [es:bx+6],ah
	mov [es:bx+8],al		;显示两位分钟数字
	
	mov al,':'
	mov [es:bx+10],al		;显示分隔符':'
	not byte [es:bx+11]		;反转显示属性
	
	pop ax
	call bcd_to_ascii
	mov [es:bx+12],ah
	mov [es:bx+14],al		;显示两位小时数字
...      

not指令:这里程序运行时这个冒号(':')将会一秒改变一次。
在这里插入图片描述

11、用IRET指令从中断过程返回

此小节代码如下,具体代码查看c09_1.asm

...
	mov al,0x20		;中断结束命令EOI(end of interrupt)
	out 0xa0,al		;向从片发送 
	out 0x20,al		;向主片发送 
	
	pop es
	pop dx
	pop cx
	pop bx
	pop ax
	
	iret
...

中断服务寄存器ISR:位为1表示正在响应对应的中断,一旦响应了该中断,8259A中断控制器芯片无法知道该中断何时结束,若不清除相应位,则下一次从该引脚来的中断将会得不到处理。
在这里插入图片描述
中断从主片来的则EOI指令只需要发给主片,要是从片来的则EOI指令。片和从片都需要发送。

IRET指令从中断处理程序返回。
在这里插入图片描述

12、用停机指令HLT使处理器进入低功耗状态

此小节代码如下,具体代码查看c09_1.asm
执行剩余程序:

...
	mov bx,done_msg                    ;显示安装完成信息 
	call put_string
	
	mov bx,tips_msg                    ;显示提示信息
	call put_string
	
	mov cx,0xb800
	mov ds,cx
	mov byte [12*160 + 33*2],'@'       ;屏幕第12行,35列
	
.idle:
	hlt		;使CPU进入低功耗状态,直到用中断唤醒
	not byte [12*160 + 33*2+1]         ;反转显示属性 
	jmp .idle
...

在虚拟机中运行:冒号一秒翻转一次、@为处理器停机之后被中断唤醒一次翻转一次
在这里插入图片描述
Virtual Box虚拟机设置:
在这里插入图片描述
Bochs虚拟机设置:
在这里插入图片描述

13、内部中断和软中断

内部中断:在处理执行指令时发生了错误或者故障引起的。

  • 比如除法指令除数为0、除法的结果溢出时产生0号中断(除法错中断)。
  • 比如遇到非法指令(指令的操作码未定义,或者指令超过了规定的长度)时产生6号中断。操作码未定义表示无法译码或执行。
  • 内部中断不受标志寄存器FLAGS的中断标志位IF的影响,处理器转到内一个中断的中断号,可以直接转到对应中断处理程序执行。

软中断:使用指令产生中断
在这里插入图片描述
int3:断点中断指令,供调试器使用故意设置的陷阱,又叫做陷阱终端,机器码是16进制的CC

调时程序可以单步执行指令,也允许设置断点,当程序执行到断电时停下,此时可以方便查看寄存器等内容。

断点就是某一条指令的起始地址,比如断点选在xor di,di,机器码是31FF处,当我们设置断点是,调试器将此条指令的机器码改为CC

当处理器执行到此条指令时,发现是机器码是CC即断点指令int3,从而转去执行断点中断处理程序,进入中断前依次压入标志寄存器FLAGSCSIP

中断处理程序是调试期提供的,任务是将断点处的处理器状态保存起来,包括标志寄存器、段寄存器以及通用寄存器的数值。同时中断处理过程会提供一个交互的界面,允许使用调试命令查看断点前的及机器状态。

在调试过程中接到继续执行的命令时,将恢复进入中断前指令的机器码,即将CC改回为31,然后修改栈中的返回地址,让此地址指向原来的那条指令即31FF

最后中断处理过程指向中断返回指令iret,重新返回到被中断的那一条指令继续向下执行。

注意:int3 != int 3
在这里插入图片描述
溢出中断指令into
在这里插入图片描述
处理器执行这条into指令时,若标志寄存器中的溢出标志OF为1,产生4号中断,否则不做任何操作。

14、BIOS中断控制概述

外部硬件中断是否能够被处理:

  • 要看中断控制器8259A是否允许中断信号到达处理器;
  • 即使中断信号到达处理器还要看标志寄存器中的中断标志位IF的状态;
  • 处理器响应中断的过程,包括向8259A发送中断响应信号;
  • 然后要求8259A芯片送来一个中断号。

内部中断、软中断不受IF位的影响。
处理器最主要的就是根据中断号找到中断处理过程,并执行这个过程。
在这里插入图片描述
8086系统中断可处理256种中断:
内部中断2%、外部硬件中断主要通过NMI引脚和8259A中断控制器芯片提供,占比7%,剩余的部分可由软件系统使用,占比91%
在这里插入图片描述

过程调用时,call指令必须指定目标位置的相对偏移量或绝对地址,在一个程序内部很方便,可以之间call 标号即可;

但是要想调用别人的代码,比如操作系统的功能,call指令就很麻烦。比如读取硬盘上的文件,因为操作系统有这样的功能,就不必自己造轮子,直接调用操作系统例程即可。但是操作系统不会给出例程的段地址和偏移地址,因为操作系统也是经常修改或者每次启动之后段地址和偏移地址都是变化的,导致例程的入口地址跟着变化。

因为有了软中断,操作系统可以使用软中断提供各种服务,每次操作系统加载完之后,将其提供的每一种服务功能做成中断处理过程,并指定以恶中断号,将服务例程地址填入中断向量表IVT中。这样程序即可使用软中断调用操作系统提供的例程了,不需要知道具体的地址,只需要一个中断号即可。

BIOS(中断功能)调用,在加载执行主引导扇区程序之前已经可以使用。BIOS提供了很多硬件服务,按照类型划分,比如键盘输入、磁盘读写、文本和图形的显示服务。每一种服务都有一个中断号,键盘服务使用的中断号为0x16,每一种服务又区分了很多功能,为了区分不同的功能,在发出软中断之前,使用ah来指定功能号。如下:

	mov ah, 0	;0号功能表示从键盘读取字符存入寄存器AL中
	int 0x16	;键盘服务
				;当中断服务例程返回之后,会监视键盘动作
				;将读取的按键字符ASCII编码存入寄存器AL中

功能号可参考配套资料中的BIOS功能调用表。
在这里插入图片描述
BIOS功能调用是在BIOS执行期间安装的,当主引导程序开始执行时即可使用,BIOS是如何建立起这一套功能调用的呢?又是如何知道访问硬件的呢?起始BIOS并不知道,很多功能调用并不是BIOS提供的,而是由我们访问的硬件自己提供的,是由外部设备接口自己建立的。

在上图中,右侧是一些外部设备接口,入板卡、显卡、硬盘控制器等等,这些接口都有自己的ROM,这些ROM中提供了自己的功能调用例程,以及本设备的初始化代码。按照规范,在这些ROM中前两个单元为55AA两个字节,第三个单元是长度(以512字节为单位的长度),从第4个单元一直响向后就是实际的功能调用例程的代码。

每一个外部设备的ROM都映射到内存地址0xC0000~~0xE0000中,如果设备存在则映射到分配给他的内存范围内。计算机启动期间会执行BIOSBIOS程序会以2K字节为单位搜索区域:0xC0000~~0xE0000,即搜索的是外部设备的ROM。若发现某个ROM的前两个字节为55AA,则表示此外社存在,BIOS会从相应的单元进入,执行设备的ROM代码。设备的ROM代码用来初始化设备本身并提供功能调用,将自己的功能调用地址填写到中断向量表中。各自填写完成之后返回到ROM BIOS,接着再搜索,再返回,直到所有的ROM都初始化完成,包括中断向量表建立完成。之后再加载执行主引导扇区程序,ROM BIOS就是这样的过程。

15、用BIOS功能调用接收并显示键盘输入

具体代码参考c09_2.asmc08_mbr.asm

显示字符使用BIOS0x10中断,0x0E号功能从键盘读取字符:
在这里插入图片描述
在这里插入图片描述
使用BIOS0x16中断,0x00号功能从键盘读取字符:
在这里插入图片描述

16、原书第9章习题

在这里插入图片描述
9.2题解:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值