基于汇编语言的音乐盒设计

基于汇编语言的音乐盒设计(可中途切换歌曲)

本程序实现的功能主要是音乐的播放,可以进行选择播放的歌曲,可以中途切换音乐,也可以退出音乐播放。程序如下:

;菜单显示
DISPLAY  MACRO B     ;定义一个宏指令,即把需要重复执行的一段代码,或者是一组指令缩写成一个宏
		 LEA DX,B
		 MOV AH,9    ;调用9号中断,将菜单显示在屏幕上
		 INT 21H
		 ENDM
		 
DATA SEGMENT

MENU     DB 0DH,0AH,'1: <<liang zhi lao hu>>'  ;歌曲1:两只老虎
		 DB 0DH,0AH,'2: <<xin nian hao>>'     ;歌曲2:新年好
		 DB 0DH,0AH,'3: <<fen shua jiang>>'   ;歌曲3: 粉刷匠
		 DB 0DH,0AH,'q: EXIT'                ;退出演奏乐曲
		 DB 0AH,0AH,'$'
		 
music1_fre DW 263,294,330,263  ;音乐1的频率
		   DW 263,294,330,263
		   DW 330,349,392
		   DW 330,349,392
		   DW 392,440,392,349,330,263
		   DW 392,440,392,349,330,263
		   DW 263,196,263
		   DW 263,196,263,0
music1_time DW 10 dup(20), 40    ;音乐1的节拍
			DW 2 dup(20), 40
			DW 4 dup(10), 20, 20
			DW 4 dup(10), 20, 20
			DW 2 dup(20), 40
			DW 2 dup(20), 40
			
music2_fre dw 262,262,262,196
           dw 330,330,330,262
           dw 262,330,392,392
           dw 349,330,294
           dw 294,330,349,349
           dw 330,294,330,262
           dw 262,330,294,196
           dw 247,294,262,0

music2_time dw 3 dup(12,12,25,25),12,12,50
            dw 3 dup(12,12,25,25),12,12,50

music3_fre	dw 392,330,392,330
		    dw 392,330,262
		    dw 294,349,330,294
		    dw 392
		    dw 392,330,392,330
		    dw 392,330,262
		    dw 294,349,330,294
		    dw 262
		    dw 294,294,349,349
		    dw 330,262,392
		    dw 294,349,330,294
		    dw 392
		    dw 392,330,392,330
		    dw 392,330,262
		    dw 294,349,330,294
		    dw 262
		    dw 0	
music3_time dw 3 dup(10h,10h,10h,10h,10h,10h,20h,10h,10h,10h,10h,40h)
		    dw 10h,10h,10h,10h,10h,10h,20h,10h,10h,10h,10h,20h
			
DATA ENDS

STACK SEGMENT

STACK ENDS			
			
CODE  SEGMENT                                                
    ASSUME DS:DATA,CS:CODE 
	
	
START:
      MOV AX,DATA
	  MOV DS,AX
	  
	  MOV AH,0
	  MOV AL,0
	  
INPUT:    ;控制音乐播放的主程序
      DISPLAY MENU   ;显示菜单
	  
	  MOV AH,1
	  INT 21H    ;调用1号中断,输入播放哪首音乐或者退出播放
	  
stop_music:
      CMP AL,'q'   ;若输入的字符为q,则中断,停止播放音乐
	  JZ end_music
	  
	  
music1:      
      CMP AL,'1'
      JNZ music2  ;若输入的数字不为1,跳转到音乐2的子程序接着判断
      lea SI,music1_fre  ;将音乐1频率的偏移地址赋值给SI
      lea BP,music1_time  ;将音乐1节拍的偏移地址赋值给BP
      CALL play_music   ;调用播放音乐子程序
      JMP INPUT        ;循环继续输入,直至按下‘4’,即退出播放

music2:      
      CMP AL,'2'
      JNZ music3  ;若输入的数字不为2,跳转到音乐3的子程序接着判断
      lea SI,music2_fre  ;将音乐2频率的偏移地址赋值给SI
      lea BP,music2_time  ;将音乐2节拍的偏移地址赋值给BP
      CALL play_music   ;调用播放音乐子程序
      JMP INPUT        ;循环继续输入,直至按下‘4’,即退出播放

music3:      
      CMP AL,'3'
      JNZ INPUT  ;若输入的数字不为3,跳转继续输入
      lea SI,music3_fre  ;将音乐2频率的偏移地址赋值给SI
      lea BP,music3_time  ;将音乐2节拍的偏移地址赋值给BP
      CALL play_music   ;调用播放音乐子程序
      JMP INPUT        ;循环继续输入,直至按下‘4’,即退出播放

end_music:                                                             
      MOV AH,4CH
      INT 21H

;*******************************************************************
sound proc near
        PUSH AX 
        PUSH BX 
        PUSH CX 
        PUSH DX 
        PUSH DI 
		;8253 芯片的设置
        MOV AL,0B6H  ;8253初始化
        OUT 43H,AL    ;43H是8253芯片控制口的端口地址
        MOV DX,12H    ;高16位
        MOV AX,34dch   ;低16位                                        
        DIV DI    ;计算分频值,赋给ax。DI中存放声音的频率值。
        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   ;开扬声器, 发声
		
WAIT1:    
        MOV CX,28000                                          
         
DELAY1:   
		nop
		loop DELAY1
        DEC BX 
        JNZ WAIT1 
        MOV AL,AH   ;恢复扬声器端口原值
        OUT 61H,AL 
        POP DI 
        POP DX 
        POP CX 
        POP BX                                                 
        POP AX 
        RET 


sound ENDP
;*************************************************************
play_music 	PROC NEAR   ;播放音乐子程序
       PUSH DS
	   SUB AX,AX
       PUSH AX

play_start:
		MOV AH,1
		INT 16H    ;这里是可以切换音乐的关键
		JNZ INPUT
     MOV DI,[SI]  ;音符
	   CMP DI,0  ;判断音符是否为0,为0则结束播放音乐子程序
	   JE end_paly
	   MOV BX,[BP]   ;节拍
	   CALL sound
	   
	   ADD SI,2
	   ADD BP,2
	   JMP play_start  ;继续执行音乐播放子程序,直至一首音乐结束
	   
end_paly:
       RET
       
       
	   
play_music endp
;*******************************************************************

CODE  ENDS 
END START   

程序执行后,按下数字键1播放音乐1,按下数字键2播放音乐2,按下数字键3播放音乐3,按下‘q’键退出音乐播放。在播放音乐的过程中可以进行切换音乐或退出,比如,按下数字键2播放音乐2,播放中途按下数字键1会停止播放音乐2转而播放音乐1。切换歌曲实现主要运用了int 16h中断,这里可以参考一位博主对该中断的解释:https://blog.csdn.net/qingkongyeyue/article/details/68490194?ops_request_misc=%7B%22request%5Fid%22%3A%22160579825619725222420556%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=160579825619725222420556&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-16-68490194.first_rank_ecpm_v3_pc_rank_v2&utm_term=汇编int+16中断&spm=1018.2118.3001.4449

猜你喜欢

转载自blog.csdn.net/qq_46068864/article/details/109829883
今日推荐