📄 music.asm
字号:
dispmsg macro message ;用来调用显示字符串的宏
mov dx,offset message
mov ah,9
int 21h
endm
data segment
;音乐播放时,提示的字符
msgdoing db 0dh,0ah,0dh,0ah
db 0dh,0ah,' Now,playing the pop music which you chose!Please enjoying...'
db 0dh,0ah,0dh,0ah,'$'
;提示选择乐曲
msgchoose db 0dh,0ah,'Input the number(1~3) <q to exit>to choose the music you want,input:','$'
;提示输入字符错误
msgerror db 0dh,0ah,0dh,0ah,0dh,0ah,'!!! sorry, you input a wrong number!!!',0dh,0ah
db 'please try to choose from 1 to 3 again<q to exit>!,input:','$'
;以下是显示音乐菜单的字符串
msgmenu db'************************************** ',0dh,0ah
db'* The pop music menu is that: * ',0dh,0ah
db'* * ',0dh,0ah
db'* 1:dahai * ',0dh,0ah ;张宇生《大海》
db'* 2:dongfengpo * ',0dh,0ah ;周杰伦《东风破》
db'* 3:dashetou * ',0dh,0ah ;吴克群《大舌头》
db'************************************** ',0dh,0ah,'$'
;以下对应为各乐曲的频率表和节拍时间表
freq_dahai dw 196,220
dw 262,262,262,262,262,220,196
dw 262,262,262,262,294,262,220,262
dw 294,294,294,294,294,262,220
dw 294,294,294,294,330,294,330,392
dw 440,440,392,440,392,330
dw 294,294,330,294,262,220,196,220
dw 262,262,262,262,262,220
dw 262,196,220
dw 440,440,392,440,524,440
dw 392,330,294,262,220,196,220
dw 262,262,262,262,294,262
dw 262,330,392
dw 440,440,440,440,524,440
dw 392,392,392,440,392,330,294
dw 262,262,262,262,294
dw 330,330,294
dw 262,262,262,262,524,440
dw 392,392,392,440,392,330,392
dw 440,524,524,440,392
dw 392,330,392
dw 440,440,440,440,524,440
dw 392,392,392,440,392,330,294
dw 262,262,262,262,392
dw 330,330,294
dw 262,262,262,262,294,330
dw 392,392,330,392,330,392
dw 440
dw 9,9,196,660,294,294,262
dw 262,-1 ;最后一个以“-1”控制结束
time_dahai dw 400,400
dw 400,200,400,400,800,400,400
dw 400,200,400,200,200,800,400,400
dw 400,200,400,400,800,400,400
dw 400,200,400,200,200,800,400,400
dw 400,800,400,800,400,400
dw 400,200,200,400,400,800,400,400
dw 400,200,400,400,800,800
dw 1600,800,800
dw 400,800,400,800,400,400
dw 400,400,400,400,800,400,400
dw 400,800,400,800,400,200
dw 2400,400,400
dw 400,800,400,800,400,400
dw 400,800,200,200,800,400,400
dw 400,800,400,800,800
dw 2400,400,400
dw 400,800,400,800,400,400
dw 400,800,200,200,800,400,400
dw 800,400,800,400,200
dw 2400,400,400
dw 400,800,400,800,400,400
dw 400,800,200,200,800,400,400
dw 400,800,400,800,800
dw 2400,400,400
dw 400,800,400,800,400,400
dw 400,800,400,800,400,400
dw 3200
dw 800,400,400,400,400,400,400
dw 4000
freq_dongfengpo dw 294,262,294,330,294,262,294,262,262,220,294
dw 294,262,294,330,294,262,294,262,262,220,196
dw 392,392,330,330,330,330,349,392,349,349
dw 294,294,330,294,262,220,262,440,440,440,392,392
dw 294,262,294,330,294,262,294,262,262,220,294
dw 294,220,262,294,262,294,330,392,392,330,392
dw 392,392,392,440,330,349,392,440,349
dw 294,294,262,330,294,262,220,294,262,294,262
dw 392,392,392,440,494,440,392,330,330,330,294,294
dw 392,392,392,330,294,294,262,294,262,294,330,330
dw 247,247,294,330,294,330,392,330,294,262,294,220
dw 262,262,294,330,294,330,392,440,392,392,330,330,330,330,294
dw 392,392,392,440,494,440,392,330,330,330,294,294
dw 392,392,392,330,294,294,262,294,262,294,330,330
dw 247,247,294,330,294,330,392,440,392,392,330,392,440,440,392,330,392,330,292
dw 294,294,262,330,294,262,220,294,262
dw -1
time_dongfengpo dw 800,800,800,1600,800,800,800,800,800,800,1600
dw 800,800,800,1600,800,800,800,800,800,800,1600
dw 800,800,800,800,800,800,800,1600,800,1600
dw 800,800,800,800,1000,800,800,800,800,800,800,800
dw 800,800,880,1600,800,800,800,800,800,800,1000
dw 800,800,800,1600,800,400,800,800,800,800,1600
dw 800,800,800,1600,800,800,1600,800,800,1000
dw 800,800,800,800,800,800,800,800,800,800,2400
dw 800,800,800,1600,200,800,600,800,800,800,800,1600
dw 800,800,800,800,800,800,600,800,800,800,800,1600
dw 800,800,800,800,800,800,600,800,800,800,800,1600
dw 800,800,800,800,800,800,600,800,800,800,800,800,800,800,800
dw 800,800,800,1600,200,800,600,800,800,800,800,1600
dw 800,800,800,800,800,800,600,800,800,800,800,1600
dw 800,800,800,800,800,800,600,800,800,800,800,1600,800,800,800,1600,400,800,600
dw 800,800,800,800,800,800,600,800,4000
freq_dashetou dw 524,524,524,524,494,524,588,524
dw 524,524,524,524,494,524,494,392
dw 524,524,524,524,494,524,588,524
dw 330,330,294,294,262,330,300,262
dw 524,524,524,524,494,524,588,524
dw 524,524,524,524,494,524,494,392
dw 524,524,524,524,494,524,588,524
dw 330,330,294,294,262,330,300,262
dw -1
time_dashetou dw 500,500,500,500,1000,500,500,500
dw 500,500,500,500,1000,500,500,500
dw 500,500,500,500,1000,500,500,500
dw 500,500,500,250,250,500,500,1000
dw 500,500,500,500,1000,500,500,500
dw 500,500,500,500,1000,500,500,500
dw 500,500,500,500,1000,500,500,500
dw 500,500,500,250,250,500,500,1000
table dw music1,music2,music3 ;取得各个标号的偏移地址
data ends
;主程序
code segment
assume cs:code,ds:data
begin:mov ax,data
mov ds,ax
next: dispmsg msgmenu
dispmsg msgchoose ;提示菜单及输入数字
inputbegin:mov ah,01h
int 21h
cmp al,'q' ;输入q则退出
je exit
cmp al,'1' ;比较数字<1?
jb doagain
cmp al,'4' ;比较数字>4?
ja doagain
and ax,000fh ;将ASCII码转换成数字,以便后面指向table表里对应的地址
dec ax ;减1,对应地址
shl ax,1 ;相当于ax*2,因为table里的相邻偏移地址是2
mov bx,ax
jmp table[bx] ;(段内)间接转移:IP<--[table+bx]跳到table里面对应的程序段
exit: mov ah,4ch
int 21h
;***************输入错误时处理的程序[提示:再次输入]********************
doagain:dispmsg msgerror
jmp inputbegin
;**********************以下对应为各乐曲的处理程序************************
music1:dispmsg msgdoing
mov si,offset freq_dahai
mov di,offset time_dahai
m1: mov cx,[si]
cmp cx,-1
je next
mov bx,[di]
call gensound
add si,2
add di,2
jmp m1
music2:dispmsg msgdoing
mov si,offset freq_dongfengpo
mov di,offset time_dongfengpo
m2: mov cx,[si]
cmp cx,-1
je next
mov bx,[di]
call gensound
add si,2
add di,2
jmp m2
music3:dispmsg msgdoing
mov si,offset freq_dashetou
mov di,offset time_dashetou
m3: mov cx,[si]
cmp cx,-1
je xx
jmp xx1
xx: jmp next
xx1: mov bx,[di]
call gensound
add si,2
add di,2
jmp m3
;***********************音乐处理子程序*************************
gensound proc near
push dx
mov al,0b6h ;向计数器写控制字
out 43h,al ;方式3、双字节写和二进制计数方式写到控制口
mov dx,08h ;设置被除数
mov ax,3208h
div cx ;其商为预置值
out 42h,al ;先送LSB
mov al,ah
out 42h,al ;后送MSB
in al,61h ;读端口原值
mov ah,al
or al,3
out 61h,al ;接通扬声器
l2: push dx
push ax
mov dx,8h
mov ax,0f05h
s1: sub ax,1
sbb dx,0
jnz s1
pop ax
pop dx
dec bx
jnz l2
mov al,ah ;写回61h端口值,关闭扬声器
out 61h,al
pop dx
ret
gensound endp
code ends
end begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -