基于上一篇文章,汇编实现背景音乐的播放的理论知识,然后改编了一个小小的键盘钢琴的实现。如果对于实现的原理不太明白,就去看上一篇博客。
下面是实现的程序:
;汇编实现键盘钢琴
data segment
DIDAS EQU 1 ;延时(时钟嘀嗒次数)
frequency dw 441,495,556,589,661,742,833 ;中音频率
times dw 0,0
data ends
stack segment stack
stk db 200 dup (?)
stack ends
code segment
assume cs:code, ds:data
start:
mov ax, data
mov ds, ax
enter_digit:
mov ah, 1
int 21h
call digit_music
jmp enter_digit
exit_proc:
mov ah,4ch ;结束程序
int 21h
;---------数字键盘发声--------
digit_music proc near
push ax
push bx
push si
cmp al, '1'
jb exitk
cmp al, '7'
ja exitk
and al, 0fh
dec al
shl al, 1
mov bl, al
lea si, frequency[bx] ;对应的频率值地址
call musick
pop si
pop bx
pop ax
exitk:
ret
digit_music endp
; -----------------------------------------
; Subroutine 延时指定的时钟嘀嗒数
; 入口:
; Didas=时钟嘀嗒数(1秒钟约嘀嗒18.2次,10秒钟嘀嗒182次。若延时不是秒的10数次倍,误差稍微大点)
delayk proc near
push dx
push cx
xor ax, ax
int 1ah
mov Times, dx
mov times[2], cx
read_time:
xor ax,ax
int 1ah
sub dx, times
sbb cx, Times[2]
cmp dx, Didas
jb Read_Time
pop cx
pop dx
ret
delayk endp
; -----------------------------------------
; 入口参数
; SI=声音频率地址
musick proc near
push ax
push cx
push dx
push si
in al, 61h
or al, 3
out 61h, al ;接通扬声器
mov al, 0b6h
out 43h, al
mov dx, 12h
mov ax, 348ch
div word ptr [si]
out 42h, al
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 3
out 61h, al
mov cx, 3314
push ax
@waitf1:
in al, 61h
and al, 10h
cmp al, ah
jz @Waitf1
mov ah, al
loop @Waitf1
pop ax
call delayk ;延时
mov al, ah
out 61h, al ;关闭扬声器
pop si
pop dx
pop cx
pop ax
out 61h, al
ret
musick endp
; -----------------------------------------
code ends
end start