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