一、实验目的
- 能够通过端口访问外设信息
- 能够通过中断调用进行输入输出
- 实验内容过程记录
任务1:计算机电子琴程序——编写程序,程序运行时使PC机成为一架可弹奏的电子琴,当按下数字键1-8时,依次发出8个音调,按ESC则退出程序。
程序设计思路:
对于第一部分提前存好音符的频率数据。用DOS功能等待键盘按键,按ESC直接退出程序只识别数字1-8,把按键数字转成数组里的位置然后发声。
第二部分分三组存放低、中、高三套音符频率。改用BIOS键盘读取,靠扫描码识别按键,不受字母ASCII乱序影响。
第三部分在拓展1代码基础上,加一个标记变量记录当前音调档位。按下数字1/2/3,修改标记,分别对应低/中/高音三套音符。
源程序:
assume cs:codeseg
data segment
dw 262,294,330,349,392,440,494,524
codeseg segment
start: mov ax, data
mov ds, ax
mov si,0
play:
mov ah,1
int 21h;使用的dos输入,所以al存的ascii码
cmp al,1bh
je over
cmp al,'8'
ja play
cmp al,'1'
jb play
sub al,30h;把ascii码转换成数字
dec al;减一从0开始
mov bl,2;占两个
mul bl;×2
mov si,ax
mov al,0b6h ;8253芯片初始化
out 43h,al ;43H是8253芯片控制口的端口地址
mov dx,12h
mov ax,34dch
div word ptr [si] ;除以数据区中的数值,以获得声音的频率值
out 42h, al
mov al, ah
out 42h, al ;分两次向42H端口输出1个字,用于设置频率
in al, 61h ;读设备控制器端口原值
mov ah, al ;保存原值
or al, 3 ;打开扬声器和定时器
out 61h, al ;接通扬声器,发声
mov dx, 10 ;延时
delay0: mov cx, 30000
delay1:
nop
loop delay1
dec dx
jne delay0
mov al, ah ;恢复端口原值
out 61h, al
jmp play
over:mov ax, 4c00h
int 21h
codeseg ends
end start
遇到的问题
一开始用ASCII判断字母按键识别不全,后来换成扫描码了就能正常识别。跳转距离过长,编译报错,拆分跳转语句解决越界问题