当前位置: 首页 > news >正文

汇编语言实现音乐播放器

目标程序

用汇编语言实现一个音乐播放器,并支持点歌

Overview

乐曲是按照一定的高低、长短和强弱关系组成的音调,在一首乐曲中,每个音符的音高和音长与频率和节拍有关,因此我们要分别为3首要演奏的乐曲定义一个频率表和一个节拍时间表。
请添加图片描述

利用8253/54定时器来驱动扬声器,在8253/54中的43端口送一个控制字0B6H,该控制字对定时器2进行初始化,使定时器2准备接收计数初值。在8253/54中的42H端口装入一个16位的计数值,以建立将要产生的发声频率。把输出端口61H的0、1两位置1,发出声音。

输入不同的数字,要播放相应的音乐。因此我们要利用输入的数字来获取歌曲的频率表地址和节拍时间表地址来播放对应音乐,利用直接定址表即可迎刃而解。

在CMOS RAM中存放着当前的时间,秒、分、时、日、月、年分别存放在0,2,4,7,8,9的单元中。这些数据以BCD码的方式存放,因此我们若要输出时间还需将他们转换为ASCII码才可正确输出。

更改界面颜色。在内存地址空间中,B8000H~BFFFFH共32KB的空间,为80*25彩色字符模式的显示缓冲区。一个字符占两个字节的存储空间,低位字节存储字符的ASCII码,高位字节存储字符的属性。属性字节的格式:7:BL闪烁 6、5、4:RGB背景色 3:I高亮 2、1、0:RGB前景色。更改属性字节即可更改界面颜色。

效果预览

初始界面

请添加图片描述

开始播放

请添加图片描述

结束播放

请添加图片描述

流程图

请添加图片描述

源码

;点歌系统:
;输入不同的数字,播放相应的音乐。
;其中“1”代表《刚好遇见你》音乐,“2”代表《成都》音乐,“3”代表《暧昧》音乐。
;输入数字“0”,则退出点歌系统。
;----------------------------------------------------
stack   segment para stack 'stack'db 100 dup ('?')
stack   ends
;----------------------------------------------------
data	segment para 'data'
tip0	db	'-----------------------------------','$'
tip1	db	'|  1: just met you-- Fei Yuqing   |','$' 
tip2	db	'|  2:    ChenDu   --  Zhao Lei    |','$' 
tip3	db	'|  3:   ambiguity -- Xue Zhiqian  |','$'
tip4	db	'|  0: exit                        |','$'
tip5	db	'  --please input your choice:      ','$'
tip		dw	tip0,tip1,tip2,tip3,tip4,tip0,tip5 ;界面
tip6	db	'music over!','$'
tip7	db	'begin:','$'
tip8	db	'end  :','$'
tip9	db	'You have exited successfully.','$'
tip10	db	'input error!please input again:','$'
time	db 'yy/mm/dd hh:mm:ss','$'				;输出时间的格式
table	db 9,8,7,4,2,0							;CMOS ROM中时间信息的存放单元;----------------------------------------------------
;《刚好遇见你》
mus_freq1 dw 262,262,262dw 262,220,524,440,440,440,392dw 392,330,330,262,294,262,262dw 262,220,524,587,524,524,440dw 440,392,330,392,294,262,247dw 262,220,524,440,440,440,392dw 392,392,330,392,294,262,294dw 262,247,262,262,262,294dw 330,294,262,262,247,262,262dw -1
mus_time1 dw 25,25,25dw 25,25,25,25,50,25,25dw 25,25,25,25,50,25,25dw 25,25,25,25,50,25,25dw 25,25,25,25,50,25,25dw 25,25,25,25,50,25,25dw 25,25,25,25,50,25,25dw 25,12,12,100,25,25dw 25,12,12,25,12,12,100
;---------------------------------------------------
;《成都》
mus_freq2 dw 196,262dw 262,294,330dw 392,330,330dw 330,196dw 262dw 294,262,220dw 196,196dw 262,262,294,330dw 440,330,392dw 330,294dw 262dw 294,392dw 330,294dw 330,392dw 392,330,392dw 440,524,440dw 330,294,262dw 294,330,330dw 196,392dw 330,330dw 294,262,262dw 196,294,262dw 330,294,262dw 262dw -1
mus_time2 dw 25,75dw 50,12,12dw 25,25,25dw 25,50dw 75dw 25,25,25dw 125,25dw 75,50,12,12dw 25,25,50dw 25,25dw 75dw 50,25dw 25,100dw 25,75dw 25,25,25dw 25,25,75dw 25,50,25dw 50,25,125dw 25,100dw 25,25dw 25,25,75dw 25,50,25dw 50,12,12dw 200
;-------------------------------------------------
;《暧昧》
mus_freq3 dw 262,262,262,294,262dw 392,440,330,330,294dw 247,247,247,262,247dw 330,392,247,294,262dw 220,247,220,247,220dw 330,349,262,220,247dw 196,262,294,294dw 349,330,330,294,262,294dw 330,262,262,262,294,262dw 392,440,330,330,294dw 294,247,247,247,262,247dw 330,392,247,294,262dw 220,247,220,247,220dw 330,349,220,262,247dw 247,330,392,294,262dw -1
mus_time3 dw 25,25,25,25,25dw 25,100,25,25,100dw 25,25,25,25,25dw 25,100,25,25,100dw 25,25,25,25,25dw 25,100,25,25,75dw 25,50,50,25dw 50,25,25,25,50,25dw 75,25,25,25,25,25dw 25,100,25,25,25dw 75,25,25,25,25,25dw 25,100,25,25,100dw 25,25,25,25,25dw 25,100,25,25,25dw 100,50,25,50,75
;---------------------------------------------------
;直接定址表
mus_time  dw mus_time1,mus_time2,mus_time3
mus_freq  dw mus_freq1,mus_freq2,mus_freq3
data ends
;----------------------------------------------------
code    segment para 'code'assume cs:code,ss:stack,ds:data
music   proc farmov ax,datamov ds,axcall tips;打印界面mov bh,00;第0页mov dh,06;第7行mov dl,42;第42列mov ah,02int 10h;设置光标位置mov ah,01int 21h;键盘输入并回显input:	cmp al,30h;和'0'比较jb	end_error;调用end_error处理错误输入cmp al,33h;和'3'比较ja	end_error;调用end_error处理错误输入cmp al,30h;判断输入是否为'0'je	end_exit;调用end_exit退出程序sub al,30h;ASCII码转换为对应数字dec al;减一,因为地址从0开始mov ah,0;ax寄存器高位置0shl ax,1;每个地址数据占两个字节,向左移位实现*2mov di,ax;相对位移赋值给变地寄存器实现寄存器相对寻址mov si,mus_freq[di]mov bp,mus_time[di]mov ah,02mov dh,08mov dl,20int 10h;设置光标位置mov ah,09lea dx,tip7int 21h;显示输出push dxmov dh,08mov dl,26call timer;调用timer子程序显示开始播放时间,dh设置显示行数,dl设置显示列数pop dxfreq:mov     di,[si]cmp     di,-1je      end_mus;遇到-1时中止乐曲mov     bx,ds:[bp]call    soundf;调用发声子程序add     si,2add     bp,2jmp     freq
end_mus:mov bh,00mov dh,10mov dl,26mov ah,2int 10h;设置光标位置mov	ah,09lea dx,tip6int 21h;显示输出mov ah,02mov dh,11mov dl,20int 10h;设置光标位置mov ah,09lea dx,tip8int 21h;显示输出push dxmov dh,11mov dl,26call timer;调用timer程序显示结束时间pop dxjmp music_end;end_exit:mov bh,00mov dh,09mov dl,20mov ah,02int 10h;设置光标位置mov ah,09lea dx,tip9int 21h;显示输出jmp music_endend_error:mov ax,0b800hmov es,axmov si,7*160+44*2mov byte ptr es:[si],20h;将输入处清空,以处理第二次仍然是错误的情况mov bh,00mov dh,07mov dl,12mov ah,02int 10h;设置光标位置mov ah,09lea dx,tip10int 21h;显示输出mov bh,00;第0页mov dh,07;第7行mov dl,44;第44列mov ah,02int 10h;设置光标位置mov ah,01int 21h;键盘输入并回显jmp inputmusic_end:mov     ax,4c00hint     21h
music   endp
;-----------------------------------------------------
;发声程序
soundf	proc farpush axpush bxpush cxpush dxpush dimov al,0b6hout 43h,al;对定时器2进行初始化mov dx,12hmov ax,348Ch;12348CH/DI中存放的给定频率得到声音计数值div diout 42h,almov al,ahout 42h,al;分两次先后装入低8位和高8位的声音计数值in al,61hmov ah,alor al,3out 61h,al;将61h端口的数据0、1位置1,发声WAIT1:  mov cx,4971;4971*15.08=0.07scall waitf;调用延迟程序dec bxjnz WAIT1mov al,ahout 61h,al;恢复接口的值pop dipop dxpop cxpop bxpop axret
soundf endp
;----------------------------------------------------
;时间延迟
waitf	proc farpush ax
waitf1:in	al,61hand	al,10hcmp	al,ahje	waitf1mov	ah,alloop waitf1pop	axret
waitf	endp
;------------------------------------------------------
;打印界面 按预先设定的tip中的内容输出并更改背景颜色
tips	proc farpush axpush dspush sipush cxmov si,offset tipsub si,2mov cx,7mov al,-1
tipsf:mov bh,0inc almov dh,almov dl,12mov ah,2int 10hpush axadd si,2mov dx,[si]mov ah,09int 21hpop axloop tipsfmov ax,0b800hmov es,axmov bp,0mov si,25
colorf:;改背景颜色mov byte ptr es:[bp+si],00110000B;颜色属性add si,2cmp si,95;控制改色区域的列的范围jb colorfadd bp,160mov si,25cmp bp,160*6;控制改色区域为1-6行jb colorfpop cxpop sipop dspop axrettips	endp
;------------------------------------------------------
;显示当前时间,dh设置输出所在的行数,dl设置列数
timer proc farpush axpush dspush sipush dipush cxpush bxmov ax,datamov ds,ax
start:	mov si,offset tablemov di,offset timemov cx,6
s1:		push cxmov al,ds:[si]out 70h,al;向70h写入要访问的单元的地址in al,71h;从71h中得到指定单元的数据mov ah,almov cl,4shr	ah,cl;十位数码值add ah,30h;转换位ASCII码and al,00001111b;个位数码值add al,30h;转换位ASCII码mov ds:[di],ahmov ds:[di+1],aladd di,3inc sipop cx		loop s1mov bh,0mov ah,2int 10h;根据预先指定的dh,dl设定光标位置mov dx,offset timemov ah,9int 21h;显示输出pop bxpop cxpop dipop sipop dspop axret
timer endp
;------------------------------------------------------
code    ends
;---------------------------------------------------------end     music 11b;个位数码值add al,30h;转换位ASCII码mov ds:[di],ahmov ds:[di+1],aladd di,3inc sipop cx		loop s1mov bh,0mov ah,2int 10h;根据预先指定的dh,dl设定光标位置mov dx,offset timemov ah,9int 21h;显示输出pop bxpop cxpop dipop sipop dspop axret
timer endp
;------------------------------------------------------
code    ends
;---------------------------------------------------------end     music 

相关文章:

汇编语言实现音乐播放器

目标程序 用汇编语言实现一个音乐播放器,并支持点歌 Overview 乐曲是按照一定的高低、长短和强弱关系组成的音调,在一首乐曲中,每个音符的音高和音长与频率和节拍有关,因此我们要分别为3首要演奏的乐曲定义一个频率表和一个节拍…...

大型网站系统架构演化(Web)

大型网站系统架构演化 大型网站系统架构演化需要关注的维度涉及的技术演进过程单体架构垂直架构使用缓存改善网站性能缓存与数据库的数据一致性问题缓存技术对比Redis分布式存储方案Redis集群切片的常见方式Redis数据类型Redis 淘汰算法使用服务集群改善网站并发能力 大型网站系…...

三轴加速度计LIS2DW12开发(2)----基于中断信号获取加速度数据

三轴加速度计LIS2DW12开发.2--轮基于中断信号获取加速度数据 概述视频教学样品申请生成STM32CUBEMX串口配置IIC配置CS和SA0设置INT1设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置开启INT1中断设置传感器的量程配置过滤器链配置电源模式设置输出数据速率中断判断加速…...

Shell循环:whileuntil

一、特点:循环次数[一定]是固定的 二、while语句结构 while 条件测试 do 循环体 done 当条件测试成立(条件测试为真),执行循环体 演示: 需求:每秒显示一个数字,一…...

Redis 安装部署

文章目录 1、前言2、安装部署2.1、单机模式2.1.1、通过 yum 安装(不推荐,版本老旧)2.1.1、通过源码编译安装(推荐) 2.2、主从模式2.3、哨兵模式2.4、集群模式2.5、其他命令2.6、其他操作系统 3、使用3.1、Java 代码 —…...

项目中遇到的半导体公司

作为一个技术人,我并不是亲美,从技术的实事求是角度讲,不得不感叹欧美的半导体技术。他们的datasheet能学到的东西太多太多;我甚至佩服他们缜密的逻辑。从他们的文章中领悟我们技术到底有多low,没办法一个一个了解所有…...

汇编:call与ret/retf指令

一、call指令 ​​​​​​​ 1.1 依据位移进行转移:call 标号 1.2 实现段间转移:call far ptr 标号 1.3 转移地址在寄存器中:call 16位寄存器 1.4 转移地址在内存中 1.4.1 call word ptr 内存单元地址 1.4.2 call dword ptr 内存单元地址…...

Fiddler抓包工具之高级工具栏中的重定向AutoResponder的用法

重定向AutoResponder的用法 关于Fiddler的AutoResponder重定向功能,主要是时进行会话的拦截,然后替换原始资源的功能。 它与手动修该reponse是一样的,只是更加方便了,可以创建相应的rules,适合批处理的重定向功能。 …...

如何基于OpenCV和Sklearn库开展数据降维

大家在做数据分析或者机器学习应用过程中,不可避免的需要对数据进行降维操作,好多垂直行业业务中经常出现数据量少但维度巨大的情况。数据降维的目的是为了剔除不相关或冗余特征,使得数据易用,去除无用数据,实现数据可…...

详解SpringAop开发过程中的坑

😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783…...

【海思SS528 | VDEC】MPP媒体处理软件V5.0 | VDEC的使用总结

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

Kubernetes sample-controller 例子介绍

sample-controller sample-controller 是 K8s 官方自定义 CDR 及控制器是实现的例子 通过使用这个自定义 CDR 控制器及阅读它的代码,基本可以了解如何制作一个 CDR 控制器 CDR 运作原理 网上有更好的文章,说明其运作原理: https://www.z…...

【C/C++指针】指针*与引用的区别

指针变量的值是所指对象的地址(准确说是首地址,其类型定义其所指对象的字节长度)引用变量的值是所引用对象本身的值 1 初始化 指针变量 可不初始化 且 可以更换指向对象 int *p;//此时是个野指针,该指针变量的值是任意值&#x…...

【ArcGIS Pro微课1000例】0039:制作全球任意经纬网的两种方式

本文讲解在ArcGIS Pro中制作全球任意经纬网的两种方式。 文章目录 一、生成全球经纬网矢量1. 新建地图加载数据2. 创建经纬网矢量数据二、布局生成经纬网1. 新建布局2. 创建地图框2. 创建经纬网一、生成全球经纬网矢量 以1:100万比例尺地图分幅为例,创建经差6、维差4的经纬网…...

【二叉树】练习题终章

二叉树的销毁 void BTreeDestroy(BTNode* root) {if (root NULL)return;BTreeDestroy(root->left);BTreeDestroy(root->right);free(root); }递归展示图 使用后序销毁,如果用前序销毁的话,就会找不到根对应的子树的地址.下面就不能被销毁了&…...

flutter开发实战-实现获取视频的缩略图封面video_thumbnail

flutter开发实战-实现获取视频的缩略图封面video_thumbnail 在很多时候,我们查看视频的时候,视频没有播放时候,会显示一张封面,可能封面没有配置图片,这时候就需要通过获取视频的缩略图来显示封面了。这里使用了video…...

Prompt Toolkit探索:打造交互式CLI应用

简介:prompt_toolkit 是一个 Python 的库,它提供了一系列功能丰富的用户界面元素,比如自动完成、语法高亮、多行编辑、提示等等,让你可以轻松地构建出功能强大的命令行工具。而且,这个库还被 IPython 和 pgcli 这样的知…...

【已解决】AttributeError: module ‘gradio‘ has no attribute ‘outputs‘

问题描述 AttributeError: module gradio has no attribute outputs 不知道作者用的是哪个gradio版本,最新的版本报错AttributeError: module gradio has no attribute outputs , 换一个老一点的版本会报错AttributeError: module gradio has no attribu…...

WPF Mvvm模式下面如何将事件映射到ViewModel层

前言 平常用惯了Command绑定,都快忘记传统的基于事件编程模式了,但是Commond模式里面有个明显的问题,就是你无法获取到事件源的参数。很多大聪明肯定会说,这还不简单,通过自己写控件,给控件加个自定义属性不就行了,想要啥事件就写啥事件进去,完全自主可控。但是对于写…...

C# WPF上位机开发(计算器界面设计)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 c# wpf最大的优势就是开发业务软件比较快、效率比较高。一般来说,它的界面和逻辑部分可以同时开发。界面的部分用xaml编写即可&#xf…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

Python如何给视频添加音频和字幕

在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中&#xff0…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

云原生安全实战:API网关Kong的鉴权与限流详解

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...