音乐程序——两只老虎

对照音符和发音频率(Hz)的对应关系,将曲谱翻译作程序中需要的数据,演奏出音乐来

低音符  频率

中音符  频率

高音符  频率

1         138

1           262

1            524

2         147

2          294

2            587

3         165

3          330

3            659

4         175

4          349

4            698

5         196

5         392

5            784

6         220

6         440

6            880

7         247

7         494

7            988

根据乐谱翻译得到的数据如下:

mus_freq dw 262,294,330,262

         dw 262,294,330,262

         dw 330,349,392

         dw 330,349,392

         dw 392,440,392,349,330,262

         dw 392,440,392,349,330,262

         dw 262,392,262

         dw 262,392,262,-1

mus_time dw 2dup(25,25,25,25)

                dw 2 dup (25,25,50)

               dw 2 dup(18,6,18,6,25,25)

               dw 2 dup(25,25,50)

把这段数据放到程序的数据段。

assume cs:codeseg, ds:dataseg, ss:stackseg
dataseg segment
mus_freq dw 262,294,330,262
         dw 262,294,330,262
         dw 330,349,392
         dw 330,349,392
         dw 392,440,392,349,330,262
         dw 392,440,392,349,330,262
         dw 262,392,262
         dw 262,392,262,-1
mus_time dw 2dup(25,25,25,25)
                dw 2 dup (25,25,50)
               dw 2 dup(18,6,18,6,25,25)
               dw 2 dup(25,25,50)
dataseg ends
stackseg segment
   db 100h dup (0)
stackseg ends
codeseg segment
start:
    mov ax, stackseg
    mov ss, ax
    mov sp, 100h
    mov ax, dataseg
    mov ds, ax
    lea si, mus_freq
    lea di, mus_time

play:
    mov dx, [si]
    cmp dx, -1
    je end_play
    call sound
    add si, 2
    add di, 2
    jmp play

end_play:
    mov ax, 4c00h
    int 21h
;演奏一个音符
;入口参数:si - 要演奏的音符的频率的地址
;          di - 要演奏的音符的音长的地址
sound:
    push ax
    push dx
    push cx
    ;8253 芯片(定时/计数器)的设置
    mov al,0b6h    ;8253初始化
    out 43h,al     ;43H是8253芯片控制口的端口地址
    mov dx,12h
    mov ax,34dch
    div word ptr [si] ;计算分频值,赋给ax。[si]中存放声音的频率值。
    out 42h, al       ;先送低8位到计数器,42h是8253芯片通道2的端口地址
    mov al, ah
    out 42h, al       ;后送高8位计数器
    ;设置8255芯片, 控制扬声器的开/关
    in al,61h   ;读取8255 B端口原值
    mov ah,al   ;保存原值
    or al,3     ;使低两位置1,以便打开开关
    out 61h,al  ;开扬声器, 发声
    mov dx, [di]       ;保持[di]时长
wait1:
    mov cx, 28000
delay:
    nop
    loop delay
    dec dx
    jnz wait1
    mov al, ah         ;恢复扬声器端口原值
    out 61h, al
    pop cx
    pop dx
    pop ax
    ret
codeseg ends
end start

不要悲伤,不要心急,忧郁的日子总会过去,把时间用在丰富自己的知识上,才是正事,加油! 

                                                ——致悲伤的自己

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值