(二十五)《汇编语言(王爽)》 | 实验 14:访问 CMOS RAM

本文档详细介绍了如何通过编程从CMOS RAM中读取当前系统时间,并以年/月/日时:分:秒的格式在屏幕上显示。程序使用汇编语言实现,通过BCD码转换为十进制ASCII码,最后在指定屏幕位置显示。实验步骤包括读取年、月、日、时、分、秒各字段,以及在适当位置插入连接字符。
摘要由CSDN通过智能技术生成


1. 预备知识

  • 在 CMOS RAM 中,存放着当前的系统时间信息。年、月、日、时、分、秒,这六个信息的长度都是 1 个字节,分别对应于第 9、8、7、4、2、0 个存储单元。
  • 这些信息以 BCD 码的方式存放,每个 BCD 码以 4 位二进制表示,即每位时间信息需要 2 个 BCD 码存储,高 4 位表示十位、低 4 位表示个位。
  • 如,在屏幕上显示当前系统时间中的年份:
assume cs:code
code segment
start:
	mov al,9	;年
	out 70h,al	;传入9号单元的地址
	in al,71h	;取9号单元的内容,高4位为十位、低4位为各位
	mov ah,al
	mov cl,4
	shr ah,cl			;高4位 
	and al,00001111b	;低4位
	add ah,30h
	add al,30h	;转换为十进制的ASCII码值
	mov bx,0b800h
	mov es,bx 
	mov es:[160*12+40*2],ah 
	mov byte ptr es:[160*12+40*2+1],2h
	mov es:[160*12+40*2+2],al
	mov byte ptr es:[160*12+40*2+3],2h
	mov ax,4c00h
	int 21h
code ends
end start

程序运行结果:

请添加图片描述


2. 实验任务

编程:以年/月/日 时:分:秒的格式,显示当前的日期、时间。

预备知识展现了在屏幕中显示当前的年信息,实验要求以特定格式显示所有时间信息,依次传入不同端口地址,读取不同端口信息即可获得当前的时间信息。结合预备知识,逐步获取时间字段然后存入实验要求的格式即可。为了简化程序,本文使用子程序调用简化字符的显示。首先,数据段存放端口地址和中间字符:

data segment
	db '9/8/7 4:2:0'	;数据段存放端口地址和中间字符
data ends 

配合 jmp 指令判断当前字符是否为数字,如果为数字则根据该数字去对应 CMOS 单元读取时间,否则直接显示,数字的 ASCII 码值的范围为 [48, 57]:

mov cl,ds:[si]	;取字符
cmp cl,48
jb show_ch		;ASCII码值小于48则转移至show_ch
cmp cl,57		
ja show_ch		;ASCII码值大于57则转移至show_ch
call get_ch		;根据端口地址取对应单元的内容

如果当前字符为数字,则读取 CMOS 对应单元的内容:

sub cl,48			;字符转换为整数
mov al,cl			;传入指定端口号
out 70h,al
in al,71h			;取对应端口的内容,高4位为十位、低4位为个位
mov ah,al
mov cl,4
shr ah,cl			;高4位
and al,00001111b	;低4位
add ah,30h			;转换为十进制的字符形式
mov es:[bx+di],ah 
mov byte ptr es:[bx+di+1],2h 	;显示十位
add di,2			;偏移2个字节写字符
add al,30h			;转换为十进制的字符形式
mov es:[bx+di],al 
mov byte ptr es:[bx+di+1],2h	;显示各个位
add di,2			;偏移2个字节写字符
inc si				;偏移1个字节取字符
ret					;子程序返回

show_ch 用于显示连接字符。显示区域为 es:[bx+di],字符存放在 cl:

show_ch:
	mov es:[bx+di],cl
	mov byte ptr es:[bx+di+1],2h

外层使用循环次数为 11 的循环,整体代码为:

assume cs:code
data segment
	db '9/8/7 4:2:0'	;数据段存放端口地址和中间字符
data ends 
code segment
start:
	mov ax,data
	mov ds,ax 			;段寄存器DS指向数据段
	mov ax,0b800h
	mov es,ax			;段寄存器ES指向显示缓冲区
	mov bx,160*12+20*2	;BX存放显示偏移
	mov si,0
	mov di,0			;分别用于索引源段和目的段
	mov cx,11			;循环次数
s:
	push cx 		;保护(CX)
	mov cl,ds:[si]	;取字符
	cmp cl,48
	jb show_ch		;ASCII码值小于48则转移至show_ch
	cmp cl,57
	ja show_ch		;ASCII码值大于57则转移至show_ch
	call get_ch
	pop cx 			;恢复(CX)
	loop s 			
	mov ax,4c00h
	int 21h
show_ch:
	mov es:[bx+di],cl 
	mov byte ptr es:[bx+di+1],2h
	inc si 				;偏移1个字节取字符
	add di,2			;偏移2个字节写字符
	pop cx 				;恢复(CX)
	sub cx,1
	jmp far ptr s 		;段间转移至s处,调用show_ch后跳过get_ch及后续代码
get_ch:
	sub cl,48			;字符转换为整数
	mov al,cl			;传入指定端口号
	out 70h,al 
	in al,71h			;取对应端口的内容,高4位为十位、低4位为个位
	mov ah,al
	mov cl,4
	shr ah,cl			;高4位 
	and al,00001111b	;低4位
	add ah,30h			;转换为十进制形式
	mov es:[bx+di],ah 
	mov byte ptr es:[bx+di+1],2h 
	add di,2			;偏移2个字节写字符
	add al,30h
	mov es:[bx+di],al 
	mov byte ptr es:[bx+di+1],2h
	add di,2			;偏移2个字节写字符
	inc si 
	ret					;子程序返回
code ends
end start

程序运行结果为:

请添加图片描述


3. 总结

  • 在 CMOS RAM 中,存放着当前的系统时间信息,每个时间信息用 1 个字节表示。
  • 每个时间信息以 BCD 码的方式存放,每个 BCD 码以 4 位二进制表示,即每位时间信息需要 2 个 BCD 码存储,高 4 位表示十位、低 4 位表示个位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值