📄 zy11_programm is teacher's.asm
字号:
;选做题2
;编写一个声音程序,用键盘的1-8键发出乐音,以便可以自己演奏
;按键 字符 ASCII码
;shift+1 ! 21h
;shift+2 @ 40h
;shift+3 # 23h
;shift+4 $ 24h
;shift+5 % 25h
;shift+6 ^ 5Eh
;shift+7 & 26h
;shift+8 * 2Ah
data segment para
Table_L dw 131,147,165,175,196,220,247,262 ;低音1-7的频率
Table_M dw 262,294,330,349,392,440,494,523 ;高音1-7的频率
shift_1 equ 21h
shift_2 equ 40h
shift_3 equ 23h
shift_4 equ 24h
shift_5 equ 25h
shift_6 equ 5Eh
shift_7 equ 26h
shift_8 equ 2Ah
data ends
ss_seg segment stack
db 256 dup(?)
ss_seg ends
code segment
assume cs:code,ds:data,ss:ss_seg
main proc far
push ds ;将psp+0h处的段地址和偏移量压入堆栈以便返回操作系统
xor ax, ax
push ax
mov ax, data ;装载数据段寄存器ds,使之指向当前数据段
mov ds, ax
main_1: mov ah, 0 ;利用bios的16号中断,扫描键盘按键
int 16h ;AL中返回按键的ASCII码,AH中返回按键的扫描码
cmp al, 0dh ;判断是否为回车键,是回车键就退出
jz main_exit
cmp al, '1'
jb main_2
cmp al, '8'
ja main_2
and ax, 000fh ;说明按下的是低音1-7,与操作将ASCII码转换到数字1-8
dec al ;将数值转换成以0开始的数字,以便从表中查找频率值
shl al, 1 ;将数值乘以2,因为每个频率值是字型变量,这样才能查表准确
lea bx, Table_L
main_12:mov si, ax
mov di, [bx+si] ;从表中取频率值
mov bx, 5000 ;发声时间
call GenSound
jmp main_1
main_2: cmp al, shift_1 ;判断是否按下shift+1键
jnz main_3
mov ax, 0
jmp main_11
main_3: cmp al, shift_2 ;判断是否按下shift+2键
jnz main_4
mov ax, 2
jmp main_11
main_4: cmp al, shift_3 ;判断是否按下shift+3键
jnz main_5
mov ax, 4
jmp main_11
main_5: cmp al, shift_4 ;判断是否按下shift+4键
jnz main_6
mov ax, 6
jmp main_11
main_6: cmp al, shift_5 ;判断是否按下shift+5键
jnz main_7
mov ax, 8
jmp main_11
main_7: cmp al, shift_6 ;判断是否按下shift+6键
jnz main_8
mov ax, 10
jmp main_11
main_8: cmp al, shift_7 ;判断是否按下shift+7键
jnz main_9
mov ax, 12
jmp main_11
main_9: cmp al, shift_8 ;判断是否按下shift+8键
jnz main_10
mov ax, 14
jmp main_11
main_10:jmp main_1
main_11:lea bx, Table_M
jmp main_12
main_exit:
ret
main endp
;发声程序
;入口:di中存放的是定时器2的计数值
; bx中存放的是延时的时间
;出口:无
GenSound proc
push ax ;保护现场
push bx
push cx
push dx
push si
push di
mov al, 0b6h ;写定时器模式
out 43h, al
mov dx, 12h ;定时器分频,533h*896=123280h
mov ax, 3280h
div di ;533h*896/给定频率
out 42h, al ;写定时器2的低字节
mov al, ah
out 42h, al ;写定时器2的高字节
in al, 61h ;得到当前61h端口的设置,并保存在ah中
mov ah, al
or al, 03h ;打开扬声器发声
out 61h, al
GenSound_2:
mov cx, 3000
GenSound_1:
nop
loop GenSound_1
dec bx
jnz GenSound_2
mov al, ah ;关闭扬声器
out 61h, al
pop di ;恢复现场
pop si
pop dx
pop cx
pop bx
pop ax
ret
GenSound endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -