编程语言
首页 > 编程语言> > NASM汇编语言与计算机系统12-70号中断实时显示时间

NASM汇编语言与计算机系统12-70号中断实时显示时间

作者:互联网

本文的示例代码显示了开机之后,屏幕左上角显示时分秒的实时时间

由于显示的是动态始终,这就得先说一下CPU关于时钟芯片的一些注意项,下面的图3画出了CPU关于中断的两个引脚,NMI和INTR
在这里插入图片描述
NMI: 原则上NMI过来的中断源都必须被处理执行,但是这只是原则上,我们可以通过设置0x70端口的位7(最高位)为1,来屏蔽所有不可屏蔽的中断,图3中示意出了NMI与70端口通过与门相连,所以需要设置1,而不是0
INTR: 如果发生了中断,INTR会有信号过来,但是信号只是一个高电平1而已,但是具体发生了什么中断?CPU不得而知,这个时候就需要有一个中断控制器,在告知CPU有中断发生之后,CPU决定是否处理(标志寄存器IF标志位),如果需要处理,则通过总线,去中断控制器里读取中断号(回忆图2),找到中断程序所在地址,最后跳转到那里去执行代码,下面来说说安装中断程序的过程,如图4
在这里插入图片描述
不得不说,这个图4我画的确实不好,但是我真的没有想到更好的方式来简单的阐述8259芯片和RTC的关系,图中没有画出CMOS中ACD寄存器,也没有画出8259A主片和从片的级联关系,这是因为我觉得画多了,不好看懂,但是我画少了之后,发现效果也不是很好,只好等以后有时间再重画这个电路图了
安装中断程序步骤
1.首先设置NMI引脚为0,表示屏蔽所有不可屏蔽中断
2.设置标志寄存器的IF位为1,表示屏蔽所有可屏蔽中断
经过以上两步,CPU的执行流程就不会受中断影响了,因为如果在安装中断的过程中,发生了其他中断,很有可能程序将加载错误的地址
3.设置CMOS BIOS中的寄存器B,需要将寄存器B的一些位置1才行,分别是位7禁止每秒去bios更新时间,位4开启更新周期结束中断,位2表示使用BCD,位1开启24小时制
4.安装0x70号中断,因为RTC就是70号中断,所以要完成在屏幕上实时显示时间,就得安装70号中断,注意中断程序执行完毕之后,程序代码必须要做两件事,读取寄存器C和往8259A的两个端口写0x20命令,告知中断控制器8259芯片中断完成,否则下次中断会被8259卡在外面无法进来
5.安装完毕之后,就可以将之前的NMI和IF恢复了,然后读取一下寄存器C,因为发生中断之后,如果不读取一下寄存器C,则中断不会再次发生

cli 					;关掉可屏蔽中断
mov al,0x0b 			;设置索引为寄存器B,同时关闭不可屏蔽中断NMI引脚
or  al,0x80
out 0x70,al
mov al,0x12				;设置寄存器B,位7禁止每秒去bios更新时间
out 0x71,al 			;位4开启更新周期结束中断,位2BCD,位1开启24小时制


mov ax,0				;开始安装70号中断
mov es,ax
mov al,0x70
mov bl,4
mul bl
mov si,ax
mov bx,show_time
mov [es:si],bx
mov word [es:si+2],0x7c0

mov al,0x0c             ;随便读取一下寄存器C,否则中断不会发生
out 0x70,al
in  al,0x71
						;设置70引脚的值是0这样才能接受RTC的中断信号
in  al,0xa1             ;读8259从片的IMR寄存器 
and al,0xfe             ;设置最低位为0,其他位不变,所以and一下
out 0xa1,al             ;写回从片IMR寄存器


sti 					;打开可屏蔽中断

dont_stop:				;hlt低功耗运行,等待各种中断的发生
hlt
jmp dont_stop

show_time:
mov ax,0xb800
mov ds,ax

mov al,0x04 			;从04索引读小时BCD信息保存到al
out 0x70,al
in  al,0x71
call show_BCD_number
mov byte [0],al
mov byte [1],0x0b
mov byte [2],bl
mov byte [3],0x0b

mov byte [4],':'
mov byte [5],0x0b

mov al,0x02 			;从02索引读分钟BCD信息保存到al
out 0x70,al
in  al,0x71
call show_BCD_number
mov byte [6],al
mov byte [7],0x0b
mov byte [8],bl
mov byte [9],0x0b

mov byte [10],':'
mov byte [11],0x0b

mov al,0x00 			;从00索引读分钟BCD信息保存到al
out 0x70,al
in  al,0x71
call show_BCD_number
mov byte [12],al
mov byte [13],0x0b
mov byte [14],bl
mov byte [15],0x0b

mov al,0x20              ;设置摩托罗拉8259A芯片的值是HEX20表示中断已经结束
out 0xa0,al
out 0x20,al

mov al,0x0c
out 0x70,al
in  al,0x71

iret
;处理BCD编码,将al中的BCD码转换成ascii
;将al高4放到al低4位中,并且al低4位保存的是ascii
;将al低4为放到bl低4中,并且bl低4位保存的是ascii
show_BCD_number:		
xor  bx,bx				
mov  bl,al
shr  al,4				;保留高4位
add  al,48d				;BCD转换ASICC需要+64

and  bl,0x0F			
add  bl,48d
ret
times 510-($-$$) db 0
dw  0xAA55

标签:12,中断,寄存器,al,mov,BCD,70,byte,NASM
来源: https://blog.csdn.net/u011624903/article/details/111054844