《汇编语言》王爽(第四版) 第十四章 检测点及实验14

文章目录

目录

前言

一、检测点

1.检测点14.1

(1)检测点14.1.(1)

(2)检测点14.1.(2)

2.检测点14.2

(1)实验任务

(2)实现代码

二、实验14 访问CMOS RAM

1.实验任务

2.思路分析

(1)读取并显示月份数据

(2)读取多项数据

3.实现代码

总结


前言

本文是王爽老师《汇编语言》(第四版) 第十四章 检测点及实验14 访问CMOS RAM 的分析及代码。


一、检测点

1.检测点14.1

(1)检测点14.1.(1)

实验任务:编程,读取CMOS RAM的2号单元的内容。

思路分析:

第一步,将要访问的地址(2H)送入地址端口,即70H端口;

第二步,从数据端口(即71H)读取相应地址(2H)的内容。

test14_1_1:     ;第14章 检测点14.1(1)
    ;实验任务:读取CMOS RAM的2号单元的内容

    mov al,2    ;2是要发送到70H地址端口的数据,表示要访问的是地址2H
    out 70H,al  ;将al中的数据输出到端口70H
    in al,71H   ;从71H号数据端口读出2号单元的内容,送入al

    ;读取结果: al=当前时钟分针读数

    ret

(2)检测点14.1.(2)

实验任务:编程,向CMOS RAM的2号单元写入0。

思路分析:

第一步,将要访问的地址(2H)送入地址端口,即70H;

第二步,向数据端口(71H)输出数据0。

test14_1_2:     ;第14章 检测点14.1(2)
    ;实验任务:向CMOS RAM的2号单元写入0

    mov al,2    ;2是要发送给70H地址端口的数据,表示要访问的是地址2H
    out 70H,al  ;将al中的数据输出到地址端口70H
    ;mov al,0    ;0是要发送给71H数据端口的数据,表示要传送的数据是0
    out 71H,al  ;将al中的数据输出到数据端口71H

    ret

2.检测点14.2

(1)实验任务

编程,用加法和移位指令计算ax = ax*10。

思路分析:10=2+8,因此这个计算等价于 ax *2 + ax*8 。shl是逻辑左移指令,相当于将数据*2,shr是逻辑右移指令,相当于将数据/2。

(2)实现代码

test14_2:   ;第14章 检测点14.2
    ;编程,用加法和移位指令计算ax = ax*10
    ;思路: ax*10 = ax*2 + ax*8
    ;给定参数:ax为待计算的值
    ;返回:ax返回结果

    mov ax,3    ;给定ax的值
    
    ;计算 ax*2
    mov bx,ax   ;用bx暂存待计算的数据
    shl ax,1    ;ax = ax*2
    mov dx,ax   ;用dx暂存结果

    ;计算ax*8
    mov cl,3    ;8是2的三次方
    shl bx,cl   ;ax = ax*8

    ;两项求和
    add bx,dx

    ret

二、实验14 访问CMOS RAM

1.实验任务

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

2.思路分析

(1)读取并显示月份数据

整体思路是,从单一功能入手,将功能封装为一个子程序。因此先读取一项数据,比如月份,并将它显示在屏幕上。

(程序中将显示字符属性设置为黑底绿色,是为了方便查看,也可以设置成其它属性。)

代码如下。

assume cs:code
code segment
start:  
    mov al,8    ;访问8号地址的数据,即月份
    mov si,160*4+5*2    ;指定显示的偏移地址
    call show_one   ;读取数据并显示

    mov ax,4c00H
    int 21H

show_one:   ;功能:取CMOS RAM的指定地址的一个byte型数据,并显示在屏幕指定位置
        ;参数:al要访问的地址;si显存的偏移地址
        ;返回:无
    push es
    push ax
    push cx
    push si

    ;从CMOS RAM的端口读取指定地址的数据
    out 70H,al  ;向70H地址端口输出要访问的地址号
    in al,71H   ;从71H数据端口读取指定地址的数据

    ;将数据拆分为十位与个位数字
    mov ah,al
    mov cl,4
    shr ah,cl    ;获得十位数字
    and al,00001111B    ;获得个位数字

    ;将BCD码数字转为十进制字符形式
    add ah,30H
    add al,30H
    
    ;在屏幕指定位置显示
    mov cx,0B800H
    mov es,cx
    mov cl,02H      ;字符显示属性
    mov es:[si],ah  ;显示十位数字
    inc si
    mov es:[si],cl ;字符显示属性
    inc si
    mov es:[si],al  ;显示个位数字
    inc si
    mov es:[si],cl ;字符显示属性

    pop si
    pop cx
    pop ax
    pop es

    ret
code ends
end start

(2)读取多项数据

接下来,就可以在主程序中多次调用子程序,进行数据的读取与显示,只需要向子程序提供要访问的地址号与显存段偏移地址即可。

实验任务中要使用“/”与“:”,通过查询ASCII码表得知,“/”对应2FH,“:”对应3AH。

日期时间数据对应的地址: 年9;月8;日7;时4;分2;秒0 。

代码如下。

start:  
    mov si,160*10+32*2    ;指定显示的偏移地址

    ;显示日期
    mov cx,3
    mov al,9
    show_date:
    call show_one   ;读取并显示一项日期数据
    add si,4 
    
    cmp al,7        ;显示“/”
    je show_blank
    push ax
    mov al,2fH  
    call show_char
    add si,2
    pop ax      ;下一项日期数据
    dec al      
    loop show_date

    show_blank:
    mov al,0H    ;显示“ ”
    call show_char 
    add si,2

    ;显示时间
    mov cx,3
    mov al,4
    s_show_time:    ;显示一项时间数据
    call show_one
    add si,4

    cmp al,0       ;显示“:”
    je show_time_ok
    push ax 
    mov al,3AH
    call show_char
    add si,2
    pop ax 
    sub al,2
    loop s_show_time

    show_time_ok:
    
    mov ax,4c00H
    int 21H

3.实现代码

完整代码及效果图如下。

assume cs:code
code segment
start:  
    mov si,160*10+32*2    ;指定显示的偏移地址

    ;显示日期
    mov cx,3
    mov al,9
    show_date:
    call show_one   ;读取并显示一项日期数据
    add si,4 
    
    cmp al,7        ;显示“/”
    je show_blank
    push ax
    mov al,2fH  
    call show_char
    add si,2
    pop ax      ;下一项日期数据
    dec al      
    loop show_date

    show_blank:
    mov al,0H    ;显示“ ”
    call show_char 
    add si,2

    ;显示时间
    mov cx,3
    mov al,4
    s_show_time:    ;显示一项时间数据
    call show_one
    add si,4

    cmp al,0       ;显示“:”
    je show_time_ok
    push ax 
    mov al,3AH
    call show_char
    add si,2
    pop ax 
    sub al,2
    loop s_show_time

    show_time_ok:
    
    mov ax,4c00H
    int 21H
show_char:  ;功能:在指定位置显示一个指定的字符
        ;参数:al指定字符; si显存段偏移地址
        ;返回:无
    push es
    push bx
    push si

    mov bx,0B800H
    mov es,bx
    mov es:[si],al      ;显示指定字符
    inc si
    mov es:[si],0AH     ;显示字符属性

    pop si
    pop bx
    pop es

    ret

show_one:   ;功能:取CMOS RAM的指定地址的一个byte型数据,并显示在屏幕指定位置
        ;参数:al要访问的地址;si显存的偏移地址
        ;返回:无
    push es
    push ax
    push cx
    push si

    ;从CMOS RAM的端口读取指定地址的数据
    out 70H,al  ;向70H地址端口输出要访问的地址号
    in al,71H   ;从71H数据端口读取指定地址的数据

    ;将数据拆分为十位与个位数字
    mov ah,al
    mov cl,4
    shr ah,cl    ;获得十位数字
    and al,00001111B    ;获得个位数字

    ;将BCD码数字转为十进制字符形式
    add ah,30H
    add al,30H
    
    ;在屏幕指定位置显示
    mov cx,0B800H
    mov es,cx
    mov cl,0AH      ;字符显示属性
    mov es:[si],ah  ;显示十位数字
    inc si
    mov es:[si],cl ;字符显示属性
    inc si
    mov es:[si],al  ;显示个位数字
    inc si
    mov es:[si],cl ;字符显示属性

    pop si
    pop cx
    pop ax
    pop es

    ret
code ends
end start


总结

本文是王爽老师《汇编语言》(第四版) 第十四章 检测点及实验14 访问CMOS RAM并显示日期和时间 的分析及代码。通过这个实验,我初步了解了如何访问端口,以及如果通过CMOS RAM端口获取当前的日期和时间。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值