📄 b.asm
字号:
stack segment stack 'stack'
db 1024 dup (0)
stack ends
data segment
bword equ this byte
r0 dw (?)
r1 dw (?)
r2 dw (?)
r3 dw (?)
r4 dw (?)
r5 dw (?)
r6 dw (?)
r7 dw (?)
;---------------------------------
temp1 dw (?)
temp2 dw (?)
temp3 dw (?)
temp4 dw (?)
;---------------------------------
led1 db (?)
led2 db (?)
led3 db (?)
led4 db (?)
led5 db (?)
led6 db (?)
led7 db (?)
led8 db (?)
led9 db (?)
led10 db (?)
led11 db (?)
led12 db (?)
led13 db (?)
led14 db (?)
led15 db (?)
led16 db (?)
led17 db (?)
led18 db (?)
led19 db (?)
words db "This program is display time."
;---------------------------------
year_reg db (?)
month_reg db (?)
day_reg db (?)
s_reg db (?)
m_reg db (?)
h_reg db (?)
;---------------------------------
data ends
video segment at 0b800h
wd_buffer label word
v_buff db 25*80*2 dup (?)
video ends
program segment
;主程序开始
main proc far
assume cs:program,ds:data,ss:stack,es:video
start: push ds
mov ax,0
push ax
mov ax,data
mov ds,ax
mov ax,video
mov es,ax
mov temp1,0000h
mov temp2,184fh
mov bh,00h
call clr_screen
;;老师的程序
do_wait: lea bx,words
mov cx,0118h
mov ah,00001110b
mov r0,32
call display_word
;;开始画无聊的图
mov ah,255 ;底色
mov byte ptr r3,00 ;分隔字符的asc码
mov r4,5
mov r5,5
mov r6,24
mov r7,36
call display_table
mov ah,255 ;底色
mov byte ptr r3,00 ;分隔字符的asc码
mov r4,5
mov r5,5
mov r6,44
mov r7,56
call display_table
mov ah,236 ;底色
mov byte ptr r3,42 ;分隔字符的asc码
mov r4,7
mov r5,11
mov r6,27
mov r7,33
call display_table
mov ah,236 ;底色
mov byte ptr r3,42 ;分隔字符的asc码
mov r4,7
mov r5,11
mov r6,47
mov r7,53
call display_table
mov ah,41 ;底色
mov byte ptr r3,30h ;分隔字符的asc码
mov r4,8
mov r5,15
mov r6,37
mov r7,43
call display_table
mov ah,40h ;底色
mov byte ptr r3,00 ;分隔字符的asc码
mov r4,19
mov r5,20
mov r6,27
mov r7,29
call display_table
mov ah,40h ;底色
mov byte ptr r3,00 ;分隔字符的asc码
mov r4,19
mov r5,20
mov r6,51
mov r7,53
call display_table
mov ah,40h ;底色
mov byte ptr r3,00 ;分隔字符的asc码
mov r4,21
mov r5,22
mov r6,27
mov r7,53
call display_table
;;画图结束
mov r0,62
mov cx,1808h
mov al,00h
mov ah,228
call display_view
mov ah,1
int 16h
jz show_time
yes_key: mov ah,0
int 16h
cmp al,1bh
jnz show_time
jmp exit
show_time: call read_time
call read_date
call convert_ascii
call display_time
call display_date
jmp do_wait
exit: mov temp1,0000h
mov temp2,184fh
mov bh,0fh
call clr_screen
ret
;;老师的程序结束
main endp
;;时间的读取,注意这里的数值是BCD码
read_time proc near
mov ah,02h
int 1ah
mov h_reg,ch
mov m_reg,cl
mov s_reg,dh
ret
read_time endp
;;日期的读取,同样这里的数值也是BCD码
read_date proc near
mov ah,04h
int 1ah
mov year_reg,cl
mov month_reg,dh
mov day_reg,dl
ret
read_date endp
;;asc码的转换
convert_ascii proc near
;;定义转换asc的宏
shift_ascii macro x,y,z
mov al,x
and al,0f0h
mov cl,4
ror al,cl
add al,30h
mov y,al
mov al,x
and al,0fh
add al,30h
mov z,al
endm
;;将时间转成asc码
shift_ascii h_reg,led1,led2
shift_ascii m_reg,led4,led5
shift_ascii s_reg,led7,led8
;;将日期转成asc码
shift_ascii year_reg,led12,led13
shift_ascii month_reg,led15,led16
shift_ascii day_reg,led18,led19
;;处理其他特殊符号成asc码
mov led3,3ah
mov led6,3ah ;备注:“:”的asc码为3ah
mov led10,32h
mov led11,30h ;这行和上面一行在年份前加"20"看来千年虫问题在80x86汇编中没有解决啊
mov led14,2dh
mov led17,2dh ;备注:“-”的asc码为2dh
ret
convert_ascii endp
;;屏幕显示程序
display proc near
;;重要公式:排列位置的求法如下
;;位置buffer=row*160+col*2
;;ch=row,cl=col
push bx
push cx
push ax
mov al,160
mul ch
mov bl,cl
rol bl,1 ;相当于bl*2
mov bh,0
add bx,ax
pop ax
mov es:[wd_buffer+bx],ax ;这里暂时不明白
pop cx
pop bx
ret
display endp
;;在特定位置显示特定字符,字符的asc码保存在[bx]中,字符的个数保存在r0中
;;初始位置保存在cx中,字符颜色属性放到ah
;;注意:字符不可超过25个
display_word proc near
display_word1: mov al,[bx]
call display
inc cx
inc bx
dec r0
jnz display_word1
ret
display_word endp
display_time proc near
mov r0,8
lea bx,led1
mov cx,1800h ;第80行(18h=79),第1列(00h=0)开始显示
display_time1: mov al,[bx]
mov ah,4eh
call display
inc cx
inc bx
dec r0
jnz display_time1
ret
display_time endp
display_date proc near
mov r0,10
lea bx,led10
mov cx,1846h
display_date1: mov al,[bx]
mov ah,4eh ;设置颜色
call display
inc cx
inc bx
dec r0
jnz display_date1
ret
display_date endp
;;在屏幕上显示图案
display_view proc near
display_view1: call display
inc cl
cmp cl,80
jc no_cf
mov cl,0
inc ch
no_cf: dec r0
jnz display_view1
ret
display_view endp
;;屏幕上显示方框
;;r4=开始行,r5=结束行,r6=开始列,r7=结束列,r3=图形asc码
display_table proc near
dec r4
dec r5
dec r6
dec r7
push ax
push bx
mov al,byte ptr r5
sub al,byte ptr r4
inc al
mov bl,byte ptr r7
sub bl,byte ptr r6
inc bl
mul bl
mov r0,ax
pop bx
pop ax
mov ch,byte ptr r4
mov cl,byte ptr r6
display_table1: mov al,00h
cmp ch,byte ptr r4
jz display_go_on
cmp ch,byte ptr r5
jz display_go_on
cmp cl,byte ptr r6
jz display_go_on
cmp cl,byte ptr r7
jz display_go_on
jmp display_go_on1
display_go_on: mov al,byte ptr r3
display_go_on1: call display
inc cl
cmp cl,byte ptr r7
jc no_cfs
je no_cfs
mov cl,byte ptr r6
inc ch
no_cfs: dec r0
jnz display_table1
ret
display_table endp
;;r4=开始行,r5=结束行,r6=开始列,r7=结束列
key_process proc near
dec r4
dec r5
dec r6
dec r7
mov cl,byte ptr r6
mov ch,byte ptr r4
call display
inc cl
cmp cl,byte ptr r7
jne key_process1
mov cl,byte ptr r6
inc ch
cmp ch,byte ptr r5
jne key_process1
mov cl,byte ptr r6
mov ch,byte ptr r4
key_process1: mov ah,02
mov dh,ch
mov dl,cl
mov bx,0
int 10h
key_process endp
;;清屏程序
clr_screen proc near
mov ah,06h
mov cx,temp1
mov dx,temp2
int 10h
mov ah,02h
mov dh,24
mov dl,80
mov bh,0
int 10h
ret
clr_screen endp
program ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -