内容:
使用汇编编写音乐播放程序,编写3个以上乐曲,在播放之前可以选择播放的曲目
思路:
子程序说明:
.8086:
stacks segment
stack db 256h dup(0)
stacks ends
data segment
welcome db 0dh, 0ah, 'Welcome to music player!', '$'
info_1 db 0dh, 0ah, 'Please select!', '$'
info_2 db 0dh, 0ah, 'Input ERROR!Please input again!', '$'
info_3 db 0dh, 0ah, 'Version 1.0.0 ALL copyright reserved!', '$'
info_4 db 0dh, 0ah, 'Please input again!', 0dh, 0ah, '$'
mus_list db 0dh, 0ah, '1 dingdingding'
db 0dh, 0ah, '2 Boat in Taihu Lake'
db 0dh, 0ah, '3 2 Tigers'
db 0dh, 0ah, '4 music'
db 0dh, 0ah, '5'
db 0dh, 0ah, 'esc exit'
db 0dh, 0ah, '$'
mus_freq_1 dw 330, 294, 262, 294, 3 dup(330) ;频率
dw 3 dup(294),330,392,392
dw 330,294,262,294,4 dup(330)
dw 294,294,330,294,262,-1
mus_time_1 dw 6 dup(25),50 ;节拍表
dw 2 dup(25,25,50)
dw 12 dup(25),100
;太湖船
mus_freq_2 dw 330, 392, 330, 294, 330, 392, 330, 294, 330
dw 330, 392, 330, 294, 262, 294, 330, 392, 294
dw 262, 262, 220, 196, 196, 220, 262, 294, 330, 262
dw -1
mus_time_2 dw 3 dup(50), 25, 25, 50, 25, 25, 100
dw 2 dup(50, 50, 25, 25), 100
dw 3 dup(50, 25, 25), 100
;两只老虎
mus_freq_3 dw 262,294,330,262,262,294,330,262
dw 330,349,392,330,349,392,392,440
dw 392,349,330,262,392,440,392,349
dw 330,262,294,196,262,294,196,262,-1
mus_time_3 dw 25,25,25,25,25,25,25,25,25,25
dw 50,25,25,50,12,12,12,12,25,25
dw 12,12,12,12,25,25,25,25,50,25,25,50
data ends
;字符串输出
show macro b
lea dx, b
mov ah, 9
int 21h
endm
;地址
play macro a,b
lea si, a
lea bp, ds:b
call mus_player
endm
code segment
assume cs:code, ss:stacks, ds:data
main:
mov ax, data
mov ds, ax
mov ax, stacks
mov ss, ax
mov sp, 256
mov ax, 0003h
int 10h
show welcome
show info_1
show info_3
show mus_list
input:
mov ah, 01h
int 21h
cmp al, 1bh
jz exit
A_:
cmp al, '1'
jnz B_
play mus_freq_1, mus_time_1
jmp exit1
B_:
cmp al, '2'
jnz C_
play mus_freq_2, mus_time_2
jmp exit1
C_:
cmp al, '3'
jnz exit2
play mus_freq_3, mus_time_3
exit1:
show info_4
jmp input
exit2:
;call clear
;mov ax, 0003h
;int 10h
show info_2
;show welcome
show info_1
show info_3
show mus_list
jmp input
exit:
mov ah, 4ch
int 21h
;-----------------------------------------
;
soundf proc near
; di---freq
; bx---节拍
push ax
push bx
push cx
push dx
push di
mov al, 0b6h ;10110110B 对定时器2进行初始化
out 43h, al ;8253/54 43h 端口
mov dx, 12h ;ax得到送往定时器2的计数值
mov ax, 348ch ;(12, 348ch)/di = 1193100hz/freq
div di ;余数在dx中 ax为商
out 42h, al ;输出计数值到42h端口
mov al, ah
out 42h, al
in al, 61h ;读入61h端口设置到al
mov ah, al ;移入高八位
or al, 3 ;输出到61h 0,1两位置1 发声
out 61h, al ;out al->61h
;延时 硬件
wait1:
mov cx, 3314 ;装入 15.08微妙的倍数
call waitf
delay1:
dec bx
jnz wait1
mov al, ah
out 61h, al
pop di
pop dx
pop cx
pop bx
pop ax
ret
soundf endp
;-----------------------------
; 延时子程序 waitf
;cx=33144 0.5s延时
;cx=663 10ms延时
waitf proc near
push ax
waitf1:
in al, 61h ;61h PB4
and al, 10h
cmp al, ah ;是否改变
je waitf1
mov ah, al
loop waitf1 ;until cx=0
pop ax
ret
waitf endp
;-----------------------------
;发声子程序
mus_player proc near
xor ax, ax
freq:
mov di, [si] ;表中音符频率
cmp di, 0ffffh ;-1为结束标志
je end_mus
mov bx, ds:[bp] ;取出音符持续时间
call soundf
add si, 2
add bp, 2
jmp freq
end_mus:
ret
mus_player endp
;---------------------------------
clear proc near
push ax
push bx
push cx
push dx
mov ah,6 ;直接控制台i/o,输出dl中ascii码对应的字符
mov al,0 ;初始化各种参数
mov ch,0
mov cl,0
mov dh,24
mov dl,79
mov bh,7
int 10h
pop dx
pop cx
pop bx
pop ax
ret
clear endp
code ends
end main
编译环境:SublimeText+masm.exe+link.exe+Dosbox
运行截图:
正常界面
播放界面
退出