汇编实现键盘钢琴

     基于上一篇文章,汇编实现背景音乐的播放的理论知识,然后改编了一个小小的键盘钢琴的实现。如果对于实现的原理不太明白,就去看上一篇博客。

下面是实现的程序:

;汇编实现键盘钢琴
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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值