汇编实验——乐曲程序(两只老虎)
来源:互联网 发布:淘宝严打刷单 编辑:程序博客网 时间:2024/05/17 05:05
首先需要知道的是PC机是通过什么来发声的,8255(A)可编程序外围接口芯片(PPI)。PPI有三个八位寄存器,两个用于输入,一个用于输出,而输出寄存器的I/O端口为61h,这是会在程序中体现的,而该输出寄存器端口号的第0位和第1位是选择扬声器的驱动方式。用汇编实现发声系统程序,有两种方式,一种是位触发方式,另一种是定时器方式。
其中位触发方式直接使61h的PB1交替置1和0来实现脉冲电流,控制扬声器从而交替打开和关闭,产生不同音高和不同音长的声音。
而定时器方式需要用到定时器内部的Counter2和控制寄存器,它们分别对应的端口号是42h和43h。在该方式中需要将一个控制字送入43h中(类似于计算机组成原理中的ROM微指令),控制字为8位,由高到低,前两位选择计数器,第3、4位选择计数器读写指示位,第5、6和7位选择操作模式(输出脉冲的形状),最后一位选择计数值格式(0为二进制,1为BCD码格式),另外42h存放的是计算得到的延迟时间。当然61h的0和1位需要都置为1。
实现了输出一个简谱音符的同时响相应的音,之前将输出音符放在了扬声器输出声音的后面,出现了声音延迟于音符输出,在数据段mes存放数据的开头增加一个空格依然无法同步,原因很简单,在主程序段中,di、bx和si是同步增加的,程序会将空格字符与一个声音对应起来。
最后,不要问我为什么后面输出的低阶sol没有显示成5下有个小点~~
下面是“两只老虎”的参考代码:
;************************************************************************************
datasg segment
mus_freq 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
mus_time dw 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500 ;节拍决定音长
dw 5000,2500,2500,5000,1200,1200,1200,1200,2500,2500
dw 1200,1200,1200,1200,2500,2500,2500,2500,5000,2500,2500,5000
mes db 31h,32h,33h,31h,31h,32h,33h,31h,33h,34h,35h,33h,34h,35h,35h,36h
db 35h,34h,33h,31h,35h,36h,35h,34h,33h,31h,32h,35h,31h,32h,35h,31h,'$'
datasg ends
;************************************************************************************
;************************************************************************************
codesg segment
main proc far
assume cs:codesg,ds:datasg
org 100h ;链接器将之后的程序放在0100h的开始位置
;-----------------------------------------------------
start:
push ds
sub ax,ax
push ax
mov ax,datasg
mov ds,ax
;
lea di,mus_freq ;频率
lea bx,mus_time ;节拍
lea si,mes ;音符
mov cx,32d;
;-----------------------------------------------------
new_shot:
push cx
call sound
add di,2
add bx,2
add si,1
mov cx,0ffffh
;-----------------------------------------------------
silent:
loop silent
pop cx
loop new_shot
mov al,48h
out 61h,al
mov ah,4ch
int 21h
ret
main endp
;-----------------------------------------------------
sound proc near
mov ah,02h ;利用中断21h的02功能调用,显示音符简谱
and si,00ffh
mov dx,[si]
int 21h
in al,61h
and al,11111100b
sing:
xor al,2 ;将PB1置1,打开扬声器
out 61h,al
push ax
call widnth
pop ax
mov cx,dx
waits:
loop waits ;循环延迟,由此控制开关电路所产生脉冲的频率
dec WORD PTR [bx] ;实现相应节拍的声音
jnz sing
and al,11111100b ;关闭扬声器
out 61h,al
ret ;一轮实现了一个音的输出
sound endp
;-----------------------------------------------------
;-----------------------------------------------------
widnth proc near ;控制脉宽的计数值
mov ax,2801
push bx ;保存的是节拍
mov bx,50
mul bx
div WORD PTR [di] ;除以了相应的频率
mov dx,ax
pop bx
ret
widnth endp
;-----------------------------------------------------
codesg ends
;************************************************************************************
end start
;************************************************************************************
- 汇编实验——乐曲程序(两只老虎)
- 汇编乐曲编程 两只老虎
- 汇编写的一段音乐——两只老虎
- C# beep 演奏两只老虎乐曲代码[K.8]
- 两只老虎改编(天线宝宝版)
- 两只老虎
- 玲珑杯----两只老虎
- GDUT2017校赛:Problem A: 两只老虎(数学)
- 两只老虎背后的故事[转贴]
- 【单片机】单片机演奏两只老虎
- CPLD板播放音乐“两只老虎”
- 周末分享——通往成功的三只老虎
- 汇编乐曲编程
- 诺基亚联姻微软是两只火鸡还是两只老虎?
- 2017广东工业大学程序设计竞赛决赛 A 两只老虎
- 毕业前必做的20件事情--抄自两只老虎的BLOG改进版本
- 51数码时钟(调时闪烁,闹钟音乐两只老虎,闹钟时间互不影响)
- 广东工业大学第12届ACM程序设计大赛 Problem A: 两只老虎
- Oracle Trigger Typical Examples
- 如何清除本地已有的svn账号
- PAT 1004. 成绩排名 (20)
- 文章标题
- oracle序列
- 汇编实验——乐曲程序(两只老虎)
- Java Socket 读取服务器端返回数据
- android 简单列表对话框(AlertDialog.Builder().setItems())
- JDK各个版本的新特性jdk1.5-jdk8
- http://www.cnblogs.com/bigdataZJ/p/springmvc1.html
- jquery ajax 获取 后台传入base64 图片数据转成图片示例
- 在写ajax异步处理的时候可能丢失样式的几个坑
- js生成二维码,解决微信浏览器不能长按识别二维码问题。
- Mysql5.7忘记root密码及mysql5.7修改root密码的方法