鱼C论坛

 找回密码
 立即注册
查看: 2859|回复: 0

[汇编作业] 实验14访问CMOS RAM

[复制链接]
发表于 2019-3-21 23:17:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
编程, 以“年/月/日 时:分:秒”的格式,显示当前的日期、时间。
注意:CMOS RAM中存储着系统的配置信息,除了保存时间信息的单元外,不要向其他的单元中写入内容,否则将引起一些系统错误。

我对该题分别作了三种解答,一种是自己通过分析自己写的,还有两种是借鉴了@leader4 看到的思路在此基础上写的下面是相应的程序。
  1. ;该程序为我自己构思并自己写的实验14的程序,在这个程序中我主要是用的是站,利用栈的特性(先进后出)把程序从新输出成我想要的顺序
  2. assume cs:code
  3. code segment
  4. start:
  5.                 mov ax, 0h
  6.                 mov cx, 3h
  7. time_1:                                        ;因为这个程序我是把时间数据和日期数据分别输出的因为他们在CMOS RAM中排列的地址相隔字节不一样所以必须分别输出
  8.                 mov bx, ax                ;因为in会吧传出的数据传给al所以在这里用bx过度一下
  9.                 out 70h, al               
  10.                 in         al, 71h                ;把数据从CMOS RAM芯片的相应端口输出到al中
  11.                 call good_1                ;把调出来得数据从BCD码的形式转换成16位并储存在ax中
  12.                 push ax                        ;压入栈中
  13.                 mov ax, bx                ;因为out和in只能使用al和ax所以在上面用bx过度一下现在从新传给ax
  14.                 add ax, 2h                ;把ax+2是因为时间的数据在CMOS RAM中是储存在 00 02 04中的他们相同的地方就是每个字符段中都是相隔两个字节
  15.                 loop time_1
  16.                 mov cx, 3h                
  17. year_1:                                        ;日期输出,顺序和每个程序段的作用都大体相同就是偏移地址的叠加数量商有区别
  18.                 inc ax                        ;因为时间地址最后一个是储存在04偏移地址中的二日期第一个是储存在07地址中04和07差3个字节所以上面遗留下来得两个和这个相加正好就是日期的偏移地址
  19.                 mov bx, ax
  20.                 out 70h, al
  21.                 in        al, 71h
  22.                 call good_1
  23.                 push ax
  24.                 mov ax, bx
  25.                 loop year_1
  26.                
  27. show_1:                                        ;下面的的程序主要是输出,输出也是分为了两个程序段一个是时间单独输出,一个是日期因为他们中间存在一个/和:所以我单独输出了他们每个数据
  28.                 mov ax, 0b800h
  29.                 mov es, ax
  30.                 mov di, 12 * 160 + 70
  31.                 mov bx, 0
  32.                
  33. show_2:
  34.                 pop ax
  35.                 mov byte ptr es:[di], ah
  36.                 mov byte ptr es:[di + 1], 2
  37.                 mov byte ptr es:[di + 2], al
  38.                 mov byte ptr es:[di + 3], 2
  39.                 cmp bx, 2
  40.                 je        show_3
  41.                 mov byte ptr es:[di + 4], '/'
  42.                 add di, 6
  43.                 inc bx
  44.                 jmp short show_2
  45. show_3:
  46.                 add di, 2
  47.                 mov bx, 0
  48. show_4:
  49.                 pop ax
  50.                 add di, 6
  51.                 mov byte ptr es:[di], ah
  52.                 mov byte ptr es:[di + 1], 2
  53.                 mov byte ptr es:[di + 2], al
  54.                 mov byte ptr es:[di + 3], 2
  55.                
  56.                 cmp bx, 2
  57.                 je        show_5
  58.                
  59.                 mov byte ptr es:[di + 4], ':'
  60.                 inc bx
  61.                 jmp short show_4
  62. show_5:
  63.                 nop
  64.                
  65.                 mov ax, 4c00h
  66.                 int 21h
  67.                
  68. good_1:
  69.                 push cx
  70.                
  71.                 mov ah, al
  72.                
  73.                 mov cl, 4
  74.                 shr ah, cl
  75.                 add ah, 30h
  76.                 and al, 00001111b
  77.                 add al, 30h
  78.                
  79.                 pop cx
  80.                 ret
  81.                
  82.                
  83. code ends
  84. end start
复制代码



程序我分别是用int 10 第2和第9个子程序和int 21 第9子程序输出的

  1. assume cs:code, ds:data_1, ds:data_2

  2. data_1 segment
  3.                 db 9, 8, 7, 4, 2, 0                                ;这个数据段是用于定位cmos ram芯片中时间数据段中的偏移地址的,
  4. data_1 ends

  5. data_2 segment
  6.                 db 'yy/mm/dd hh:mm:ss', 0                ;用于储存从cmos ram中调出的数据的
  7. data_2 ends

  8. code segment
  9. start:                                                        ;下面的的代码段是用于从CMOS RAM芯片中通过70和71端口读取数据并把他们存入data_2中的
  10.                 mov ax, data_1
  11.                 mov ds, ax
  12.                 mov si, 0
  13.                
  14.                 mov ax, data_2
  15.                 mov es, ax
  16.                 mov di, 0
  17.                 mov cx, 6
  18. loop_1:
  19.                 mov al, byte ptr ds:[si]
  20.                 out 70h, al
  21.                 in         al, 71h
  22.                
  23.                 call good                                ;我把BCD码转换的程序单独写了一个函数存在了下面good标记段中用call跳转过去执行,这样我感觉看着更清晰
  24.                 mov byte ptr es:[di], ah
  25.                 mov byte ptr es:[di + 1], al
  26.                 add di, 3
  27.                 inc si
  28.                 loop loop_1
  29.                                                                 ;显示data_2中的数据在屏幕上这里我用了int 10 中断中的2号子程序和9子程序
  30.                 mov si, 0h
  31.                 mov dl, 12                ;循环使用int 10 ah 2
  32. show_2:
  33.                
  34.                 mov ah, 2
  35.                 mov bh, 0
  36.                 mov dh, 5
  37.                 int 10h
  38.                
  39.                 mov ah, 9
  40.                 mov bh, 0
  41.                 mov al, byte ptr es:[si]
  42.                 mov bl, 2
  43.                 mov cx, 1
  44.                 int 10h
  45.                
  46.                 inc dl
  47.                 inc si
  48.                 ;cmp byte ptr es:[si], 0                        ;用了两种跳转方式实验感觉还是jcxz好使这个留着备用
  49.                 ;je loop_3
  50.                 mov cx, 0
  51.                 mov cl, byte ptr es:[si]
  52.                 jcxz show_3
  53.                 jmp short show_2
  54. show_3:
  55.                 nop
  56.                
  57.                
  58.                 mov ax, 4c00h
  59.                 int 21h
  60.                
  61. good:
  62.                 push cx
  63.                 mov ah, al
  64.                 mov cx, 4
  65.                 shr ah, cl
  66.                 add ah, 30h
  67.                 and al, 00001111b
  68.                 add al, 30h
  69.                 pop cx
  70.                 ret
  71.                
  72. code ends
  73. end start
复制代码

  1. assume cs:code, ds:data, ds:show_x

  2. data segment
  3.                 db 9, 8, 7, 4, 2, 0
  4. data ends

  5. show_x segment
  6.                 db 'yy/mm/dd hh:mm:ss', '
  7. show_x ends

  8. code segment
  9. start:                                                        ;定位数据段把他们传给相应的寄存器
  10.                 mov ax, data
  11.                 mov ds, ax
  12.                 mov si, 0
  13.                
  14.                 mov ax, show_x
  15.                 mov es, ax
  16.                 mov di, 0
  17.                
  18.                 mov cx, 6h
  19. one_1:                                                        ;把数据从cmos ram中提取出来传给数据段show_x储存起来
  20.                 mov al, ds:[si]
  21.                 out 70h, al
  22.                 in al, 71h
  23.                 call good_1                                ;BCD转换成16进制的数据并储存在show_x中
  24.                
  25.                 mov byte ptr es:[di], ah
  26.                 mov byte ptr es:[di+1], al
  27.                 add di, 3
  28.                 inc si
  29.                 loop one_1
  30. show_1:
  31.                 mov di, 0
  32.                 mov ax, 0
  33. show_2:                                        ;这个程序我用的是int 10 第2个子程序配上int 21 第9个子程序一起使用段输出
  34.                 mov ah, 2
  35.                 mov bh, 0
  36.                 mov dh, 10
  37.                 mov dl, 35
  38.                 int 10h
  39.        
  40.                 mov ax, show_x                ;从show_x数据段中把数据输出到屏幕上
  41.                 mov ds, ax
  42.                 mov dx, 0
  43.                 mov ah, 9
  44.                 int 21h
  45.                
  46.                 mov ax, 4c00h
  47.                 int 21h
  48. good_1:                                                ;把BCD中的数据转换成16进制并储存到show_x数据段中
  49.                 push cx
  50.                
  51.                 mov ah, al
  52.                
  53.                 mov cl, 4
  54.                 shr ah, cl
  55.                 add ah, 30h
  56.                 and al, 00001111b
  57.                 add al, 30h
  58.                
  59.                 pop cx
  60.                 ret
  61.                
  62.                
  63. code ends
  64. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 00:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表