汇编语言 实验14 访问CMOS RAM

汇编语言 访问CMOS RAM


CMOS RAM

是什么?
存放计算机开机必备的一些数据的硬件,由BIOS(Basic input/output system)调用其数据。
怎么用?
首先要理解端口的概念,在计算机中,与CPU可以访问的数据的位置可以有一下三种:存储器、寄存器、端口。而端口的另一端是芯片,即CPU通过端口与其他芯片相连。在这些芯片中,都有一组可供CPU读写的寄存器。站在CPU的角度,CPU对这些寄存器统一编址。
那么怎么进行访问呢?首先要明白,CPU对于端口寄存器只有两种操作类型:in(从端口读取数据)、out(向端口输出数据)。
例如: in al,71h(从71h端口读取数据,放到寄存器al中)
      out 70h,al(将寄存器al中的数据传送到70h端口中)
      注:对端口的操作只能用al或者ax寄存器。 

输出时间程序

时间在CMOS RAM中的表示形式:
秒:在0号单元
分:2
时:4
日:7
月:8
年:9
思路:
这里可以用实验13(3)的思路,将用到的数据放在code块中,并通过offset进行访问,简单粗暴
源程序:
assume cs:code

code segment
index: db 9,8,7,4,2,0
string: db 'yy/mm/dd hh:mm:ss'

start:  mov ax,code
    mov ds,ax
    mov si,offset index
    mov bx,offset string
    mov cx,6
s:  push cx
    mov al,ds:[si]
    out 70h,al
    in al,71h
    mov ah,al
    mov cl,4
    shr ah,cl
    and al,00001111b
    add al,30h
    add ah,30h
    mov [bx],ah
    mov [bx+1],al
    inc si;最后一次循环后,指向string
    add bx,3
    pop cx
    loop s
    ;显示字符串
    mov ax,0b800h
    mov es,ax
    mov di,160*12+40*4
    mov cx,17
s0: mov al,ds:[si]
    mov es:[di],al
    add di,2
    inc si
    loop s0

ok: mov ax,4c00h
    int 21h

code ends
end start
自我总结
一开始的思路是,定义data段,将单元号放进去,然后再把‘\’和‘:’放进去(好蠢。。),然后在把从CMOS RAM中取出的al通过一个函数,直接变成:ah(高位)al(低位)。行得通,但是当我把“年”输出做好了之后,发现,还有五个要做,这样下去程序会非常长,所以必须要用循环。可是以当时的设计,做循环是不可能的,每个两位数中间都有'\'或者':'等字符。然后去瞄了一眼答案,瞬间恍然大悟。。世上那么多条路可以选,我偏偏选了最难走的那一条:( 

转载于:https://www.cnblogs.com/litlife/p/7512769.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个比较复杂的任务,需要编写一些底层的代码来访问CMOS RAM中的时间数据,并将其转换为可读的格式。以下是一个示例程序,可以在8086汇编语言下编译和运行。 ``` .MODEL SMALL .STACK 100H .DATA CUR_YEAR DW ? CUR_MONTH DB ? CUR_DAY DB ? CUR_HOUR DB ? CUR_MIN DB ? CUR_SEC DB ? CUR_WEEKDAY DB ? YEAR_STR DB 6 DUP('$') MONTH_STR DB 4 DUP('$') DAY_STR DB 4 DUP('$') HOUR_STR DB 4 DUP('$') MIN_STR DB 4 DUP('$') SEC_STR DB 4 DUP('$') WEEKDAY_STR DB 10 DUP('$') MSG DB 'Current time and date:', '$' .CODE MAIN PROC ; Set up data segment MOV AX, @DATA MOV DS, AX ; Display message MOV AH, 09H LEA DX, MSG INT 21H ; Read time data from CMOS RAM MOV AH, 0 INT 1AH ; Extract time values MOV AL, CH ; Year (century) AND AL, 0FH MOV AH, 10 MUL AH MOV CUR_YEAR, AX MOV AL, CL ; Year (last two digits) AND AL, 0FH MOV AH, 10 MUL AH ADD CUR_YEAR, AX MOV CUR_MONTH, DH ; Month MOV CUR_DAY, DL ; Day MOV CUR_HOUR, CH ; Hour MOV CUR_MIN, CL ; Minute MOV CUR_SEC, DH ; Second MOV CUR_WEEKDAY, DL ; Weekday ; Convert time values to strings CALL WORD PTR TO_DEC ; Year MOV SI, OFFSET YEAR_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], '/' INC SI CALL WORD PTR TO_DEC ; Month MOV SI, OFFSET MONTH_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], '/' INC SI CALL WORD PTR TO_DEC ; Day MOV SI, OFFSET DAY_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], ' ' INC SI CALL WORD PTR TO_DEC ; Hour MOV SI, OFFSET HOUR_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], ':' INC SI CALL WORD PTR TO_DEC ; Minute MOV SI, OFFSET MIN_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], ':' INC SI CALL WORD PTR TO_DEC ; Second MOV SI, OFFSET SEC_STR CALL WORD PTR PRINT_STR MOV BYTE PTR [SI], ' ' INC SI MOV AX, CUR_WEEKDAY ; Weekday CALL WORD PTR TO_WEEKDAY MOV SI, OFFSET WEEKDAY_STR CALL WORD PTR PRINT_STR ; Exit program MOV AH, 4CH INT 21H MAIN ENDP ; Convert binary value to decimal ASCII string TO_DEC PROC PUSH AX PUSH BX PUSH CX PUSH DX MOV BX, 10 MOV CX, 0 MOV DX, 0 ; Divide by 10 until quotient is zero DIV BX ADD AL, '0' MOV BYTE PTR [DI], AL DEC DI INC CX CMP AX, 0 JNE TO_DEC ; Add leading zeroes if necessary CMP CX, 4 JGE DONE_TO_DEC MOV DL, '0' SUB CX, 4 ADD DI, CX REP STOSB DONE_TO_DEC: POP DX POP CX POP BX POP AX RET TO_DEC ENDP ; Convert binary value to weekday string TO_WEEKDAY PROC PUSH AX PUSH DI MOV DI, OFFSET WEEKDAY_STR CMP AX, 0 JE SUNDAY_TO_WEEKDAY CMP AX, 1 JE MONDAY_TO_WEEKDAY CMP AX, 2 JE TUESDAY_TO_WEEKDAY CMP AX, 3 JE WEDNESDAY_TO_WEEKDAY CMP AX, 4 JE THURSDAY_TO_WEEKDAY CMP AX, 5 JE FRIDAY_TO_WEEKDAY CMP AX, 6 JE SATURDAY_TO_WEEKDAY SUNDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'S' INC DI MOV BYTE PTR [DI], 'u' INC DI MOV BYTE PTR [DI], 'n' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY MONDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'M' INC DI MOV BYTE PTR [DI], 'o' INC DI MOV BYTE PTR [DI], 'n' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY TUESDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'T' INC DI MOV BYTE PTR [DI], 'u' INC DI MOV BYTE PTR [DI], 'e' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY WEDNESDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'W' INC DI MOV BYTE PTR [DI], 'e' INC DI MOV BYTE PTR [DI], 'd' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY THURSDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'T' INC DI MOV BYTE PTR [DI], 'h' INC DI MOV BYTE PTR [DI], 'u' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY FRIDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'F' INC DI MOV BYTE PTR [DI], 'r' INC DI MOV BYTE PTR [DI], 'i' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY SATURDAY_TO_WEEKDAY: MOV BYTE PTR [DI], 'S' INC DI MOV BYTE PTR [DI], 'a' INC DI MOV BYTE PTR [DI], 't' INC DI MOV BYTE PTR [DI], '$' INC DI JMP DONE_TO_WEEKDAY DONE_TO_WEEKDAY: POP DI POP AX RET TO_WEEKDAY ENDP ; Print null-terminated string PRINT_STR PROC PUSH CX PUSH DX MOV CX, 0 MOV DL, BYTE PTR [SI] CMP DL, '$' JE DONE_PRINT_STR INC SI INC CX JMP PRINT_STR_LOOP PRINT_STR_LOOP: MOV AH, 02H INT 21H MOV DL, BYTE PTR [SI] CMP DL, '$' JE DONE_PRINT_STR INC SI INC CX JMP PRINT_STR_LOOP DONE_PRINT_STR: POP DX POP CX RET PRINT_STR ENDP END MAIN ``` 这个程序通过调用INT 1AH中断来读取CMOS RAM中的时间数据,并将其转换为可读的格式。它使用了一些子过程来将二进制值转换为十进制ASCII字符串和星期几字符串。最后,它使用INT 21H中断来在屏幕上显示结果。请注意,这个程序假定CMOS RAM中的时间数据已经被正确设置,并且假定程序运行在支持CMOS RAM的计算机上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值