一个简单的汇编报时小闹钟

有些简陋,但是可以变色+滴答,却做了将近8天,还有1个下午6点-早上7点的小通宵。熬得头大,但是每当解决完一个问题或者发现一处自己没有想到的地方时,心情确实格外的高兴,总体的收获就是-磨刀不误砍柴工啊,很多中断只是看了提示或者例题就开做,出错的时候迷惑的一塌糊涂,也许开始就仔细的看完中断会给后来带来很大的节省。

1.在自定义1ch中断时,要注意定义的中断尽量不要调用过于复杂的过程,甚至不调用过程,我在这上面吃亏吃了很惨。调试了整整一晚上。。。改用为倒数18次后,在主函数中通过查看标志变量来达到一秒更新钟表的效果。

2.表盘数字,参考他人的程序,直接按照定位光标+输出字符来硬编码出我们的表盘。

3.指针,没有用taylor展开式求正弦值,而是简单的使用正弦表,产生正弦表很简单O,比算正弦简单。

正弦
import sys
import math
file
=open("c:\sin.txt","w")
for i in range(0,360):
result
=int(math.sin(i*2*math.pi/360)*100)
str
= " db %s\n" %result
file.write(str)
file.close()

4.我们开始根据时间算出来的角度是针对12点的,所以要回退90度,但是这样计算需要判断情况比较多才能保证角度为正值,所以我们可以直接+270,超过360再进行缩减。

5.每秒重绘指针,关键是保存旧的三个指针角度,然后绘制新的指针,比较复杂,我倾向于直接重绘屏幕。

6.滴答声,简单的用扬声器的中断,不停的0101就行了。

汇编代码好长,删掉那个正弦表发上来O

之前写的时候,可以实现按任意键退出,但是后来迷失了。。。

clock
pusha macro
push ax
push bx
push cx
push dx
push si
push di
endm
POPA macro
pop di
pop si
pop dx
pop cx
pop bx
pop ax
endm
clear macro
pusha
mov ah,6
mov al,0
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,0
int 10h
popa
endm
data segment
time_up db
0
count db
18
R2 dw
13000
flag db
0
window_width dw
640
window_height dw
480
color db
10
R dw
120
D dw
180
mid_line dw
320 ;cx x-
mid_row dw 246 ;dx y-
edge_line dw 600
edge_row dw
400
round_r db
30
round_m db
6
len_of_sin dw ?
_cos dw ?
_sin dw ?
_thi dw ?
check_sin dw
0
dw .....
DATA ENDS
STACK SEGMENT
LENG DW
120 DUP(?)
TOP EQU $-LENG
STACK ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME
CS:CODE,DS:DATA,ES:data,SS:STACK
;; INIT
START: PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AH,2CH
INT 21H
;;SET WINDOW_WIDTH X WINDOW_HEIGHT
MOV AL,12H
MOV AH,00H
int 10h
mov ax,window_width
mov cx,window_height
mov count,18
;; 保存原位置中断
mov al,1ch
mov ah,35h
int 21h
push es
push bx
;; 设定中断号
push ds
mov dx,offset ring
mov ax,seg ring
mov ds,ax
mov al,1ch
mov ah,25h
int 21h
pop ds
mov al,11111100b ;for keybord & timer
out 21h,al
draw_clock:
call draw_all
input:
sti
cmp time_up,1
jz draw_clock
in al,60h
jmp input
next_input:
jmp input
quit:
cli
mov cx,ds
pop dx
pop ds
mov ds,cx
sti
ret
main endp

ring proc near
push ds
push ax
push cx
push dx
mov ax,data
mov ds,ax
mov time_up,0
dec count
jnz exit
mov time_up,1
mov count,18
exit:
cli
pop dx
pop cx
pop ax
pop ds
iret
ring endp

draw_noodle proc near
pusha
mov ah,2ch
int 21h
cmp ch,0ch ;; hour
jle no_dec_12
sub ch,0ch
no_dec_12:
mov al,ch
mul round_r
mov ch,cl
shr ch,1
add al,ch
adc ah,0
push ax
;; minute:minute*6+second/8(10)
mov al,cl
mul round_m
mov bl,cl
mov cl,3
mov dl,dh
shr al,cl
add al,bl
adc ah,0
push ax
;; second:second*6
mov al,dh
mul round_m
push ax
mov bx,100
mov cx,3
draw_line:
mov len_of_sin,bx
pop ax
add ax,270
cmp ax,360
jle no_add
sub ax,360
no_add:
call sin
sub bx,20
loop draw_line
popa
ret
draw_noodle endp

draw_number PROC NEAR
pusha
MOV AL,10h
MOV BX,R
;; 12 ; 12
MOV DH,7 ; 11 1
MOV DL,39 ; 10 2
CALL draw_point ; 9 3
MOV DL,'1' ; 8 4
MOV AH,2 ; 7 5
INT 21h ; 6
MOV DH,7
MOV DL,40
CALL draw_point
MOV DL,'2'
MOV AH,2
INT 21h
;; 11
MOV DH,8
MOV DL,30
CALL draw_point
MOV DL,'1'
MOV AH,2
INT 21h
MOV DH,8
MOV DL,31
CALL draw_point
MOV DL,'1'
MOV AH,2
INT 21h
;; 1
MOV DH,8
MOV DL,47
CALL draw_point
MOV DL,'1'
MOV AH,2
INT 21h
;; 10
MOV DH,11
MOV DL,25
CALL draw_point
MOV DL,'1'
MOV AH,2
INT 21h
MOV DH,11
MOV DL,26
CALL draw_point
MOV DL,'0'
MOV AH,2
INT 21h
;; 2
MOV DH,11
MOV DL,53
CALL draw_point
MOV DL,'2'
MOV AH,2
INT 21h
;; 9
MOV DH,15
MOV DL,24
CALL draw_point
MOV DL,'9'
MOV AH,2
INT 21h
;; 3
MOV DH,15
MOV DL,55
CALL draw_point
MOV DL,'3'
MOV AH,2
INT 21h
;; 8
MOV DH,19
MOV DL,26
CALL draw_point
MOV DL,'8'
MOV AH,2
INT 21h
;; 4
MOV DH,19
MOV DL,53
CALL draw_point
MOV DL,'4'
MOV AH,2
INT 21h
;; 5
MOV DH,22
MOV DL,47
CALL draw_point ;
MOV DL,'5'
MOV AH,2
INT 21h
;; 7
MOV DH,22
MOV DL,32
CALL draw_point
MOV DL,'7'
MOV AH,2
INT 21h
;; 6
MOV DH,23
MOV DL,40
CALL draw_point
MOV DL,'6'
MOV AH,2
INT 21h
popa
RET
draw_number ENDP

draw_point PROC NEAR
MOV BH,0
MOV AH,02h
INT 10h
RET
draw_point ENDP

draw_cloth proc near
pusha
;; heart of the circle
mov bh,0h
mov cx,mid_line
mov dx,mid_row
mov al,color
mov ah,0ch
int 10h
;; draw the surface
sub cx,R ;cx:line-R=x_mix
jns out_next
neg cx
out_next:
mov dx,mid_row ;dx:row-R=y_mix
sub dx,R
jns in_next
neg dx
in_next:
call calculate_R
mov al,flag
cmp al,1
jnz test_D
mov bh,0h
mov al,color
mov ah,0ch
int 10h
test_D: inc dx
cmp dx,edge_row
jl in_next
inc cx
cmp cx,edge_line
jl out_next
popa
ret
draw_cloth endp
; Test.make.flag 1-------------------------------------------------
calculate_TestR proc near
mov si,dx
mov di,cx
mov cx,di
mov dx,si
mov flag,1
ret
calculate_TestR endp
;
;
Judge is the R distance--------------
calculate_R proc near
pusha
mov si,cx
mov di,dx
mov flag,0
;; cx:bx=(x1-x2)*(x1-x2)
mov ax,cx
sub ax,mid_line
imul ax
; jc fail_equal
mov cx,dx
mov bx,ax
;; (y1-y2)2
mov ax,mid_row
sub ax,di
imul ax
; jc fail_equal
;;dx:ax=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)
add ax,bx
adc dx,cx
cmp dx,0
jnz fail_equal
mov bx,R2
sub bx,120
mov cx,R2
add cx,120
cmp ax,bx
jb fail_equal
cmp ax,cx
ja fail_equal
mov flag,1
fail_equal:
mov dx,di
mov cx,si
popa
ret
calculate_R endp

sin proc near
pusha
;; ax-角度,di-半径,bx-sin扩张倍数
mov _thi,ax
mov di,len_of_sin
mov bx,100
;; ax=cos(x)
mov si,90
sub si,ax
cmp si,0
jge no_add_360
add si,360
no_add_360:
shl si,1
mov ax,check_sin[si]
mov _cos,ax
mov si,_thi
shl si,1
mov ax,check_sin[si] ;sin(x)
mov _sin,ax
draw_one:
mov ax,_cos
imul di
idiv bx
add ax,mid_line
mov cx,ax
mov ax,_sin
imul di
idiv bx
add ax,mid_row
mov dx,ax
mov bh,0
mov al,color
mov ah,0ch
int 10h
mov bx,100
dec di
jnz draw_one
popa
ret
sin endp

draw_all proc near
cli
clear
mov ah,2ch
int 21h
and dh,0fh
mov color,dh
call draw_number
call draw_cloth
call draw_noodle
mov bx,2000
mov cx,400
call sound
ret
draw_all endp

;; SOUND-sound in frequency bx,delay cx
sound proc near
pusha
mov dx,cx
in al,61h ;port 61 mask-1 connect to producter
and al,11111100b ;turn off 0、1
trig:
xor al,2 ;00000010 1->0 0->
out 61h,al
mov cx,bx
delay:
loop delay
;wait for cx time
dec dx
jne trig
popa
ret
sound endp

code ends
end start

原文地址:https://www.cnblogs.com/amaoxiaozhu/p/1933030.html