这道题本来不难,但是emu8086并不能正确的显示时间,也不能正确的运行键盘中断,我分析是因为emu8086并没有仿真实模式下
的DOS的缘故。所以去网上下载了DOSBOX解决了这个问题。DOSBOX可以 很好的运行以上的两个程序。而且速度也快了很多。
这道题我写了一个CMOS_READ函数来读取CMOS的一个字节,打印函数就用课程设计1用过的show_str 搞定。代码如下:
assume cs:code
stack segment
db 128 dup(0)
stack ends
code segment
cmos_addr: db 9,8,7,4,2,0
str: db 'yy/mm/dd hh:mm:ss',0
start:
; set segment registers:
mov ax,stack
mov ss,ax
mov sp,128
mov ax,cs
mov ds,ax
;cmos addr-->[ds:di] str-->ds[si]
mov cx,6
mov di,offset cmos_addr
mov si,offset str
L32:
mov ah,0
mov al,[di]
call cmos_read
mov [si],ah
mov [si+1],al
inc di
add si,3
loop L32
;print str
mov dh,12
mov dl,36
mov bl,7
mov si,offset str
call show_str
mov ax, 4c00h ; exit to operating system.
int 21h
delay:
push ax
push dx
mov dx,5h
mov ax,0h
L35:
sub ax,1
sbb dx,0
cmp ax,0
jne L35
cmp dx,0
jne L35
pop dx
pop ax
ret
;show string
;dh:line(0-24) dl:column(0,79),bl:color ds:si string start addr
;es:bx->0b800:offset
show_str:
;save registers
push si
push cx
push ax
push es
push bx
push dx
push bx ;save color
;init es
mov ax,0b800h
mov es,ax
;calc display memory offset according to line and columm
mov al,dh
mov cl,160
mul cl; 160 bytes per line
mov dh,0
add ax,dx ;offset = 160*line + 2*column
add ax,dx
mov bx,ax
pop ax ;restore color
mov ah,al
l:
;string end?
mov cl,[si]
mov ch,0
jcxz ok
;begin write
mov al,cl
mov es:[bx],al
;write color
mov es:[bx+1],ah
;update indexs
inc bx
inc bx
inc si
jmp short l
ok:
;recover registers
pop dx
pop bx
pop es
pop ax
pop cx
pop si
ret
;addr-->al val-->ax
cmos_read:
push cx
out 70h,al
in al,71h
mov ah,al
mov cl,4
shr ah,cl
and al,0fh
;BCD --> ascii
add ah,30h
add al,30h
pop cx
ret
code ends
end start ; set entry point and stop the assembler.