📄 experiment2.asm
字号:
d_seg segment
music_freq dw 2 dup(262, 294, 330, 262)
dw 2 dup(330, 349, 392)
dw 2 dup(392, 440, 392, 349, 330, 262)
dw 2 dup(294, 196, 262)
dw 0
music_time dw 2 dup(25,25,25,25)
dw 2 dup(25, 25,50)
dw 2 dup(12,12,12,12,25,25)
dw 2 dup(25, 25, 50)
music2 dw 0
old_seg dw ?
old_off dw ?
d_seg ends
code segment
assume cs:code, ds:d_seg
start:
mov ax, d_seg
mov ds, ax
lea si, music_freq ;音符频率表指针->SI
lea bp, music_time ;音符延时表指针->BP
in al, 61h
or al, 3
out 61h, al ;将8255的PB1,PB0置1,即将8253的GATA接通,及将扬声器打开。
begin:
mov di, [si] ;取一个频率
cmp di, 0 ;如果为0则退出
je exit
mov bx, ds:[bp] ;取一个音符节拍
sar bx,1 ;因为机器的运行速度加快,所以将延时按需增加,这里采用右移的方式
sar bx,1
call create_sound ;调用发声子程序
add si, 2 ;SI指向下个位置
add bp, 2 ;BP指向下个位置
jmp begin
exit:
in al, 61h
and al, 11111100b
out 61h, al ;将8255的PB1,PB0置0,即将8253的GATA断开,及将扬声器关闭。
mov ah, 4ch
int 21h ;返回DOS
create_sound proc near
mov al, 10110110b ;初始化命令方式,(10-通道2)(11-先读写低字节,再读写高字节)(011-方式3)(0-二进制)
out 43h, al ;将初始化命令写入8253的控制器
mov dx, 12h
mov ax, 34DCH
div di ;计算定时常数
out 42h, al ;写入低字节
mov al, ah
out 42h, al ;写入高字节
call delay ;延时
ret
create_sound endp
NEW_1CH PROC NEAR ;课本P224
DEC BX
IRET
NEW_1CH ENDP
delay proc near
pushf
push ds
push es
push bx
mov ax,351ch
int 21h
mov old_off,bx
mov bx,es
mov old_seg,bx
pop bx
pop es
mov ax,251ch
mov dx,seg NEW_1CH
push ds
mov ds,dx
mov dx,offset NEW_1CH
int 21h
pop ds
again:
cmp bx,00h
jnz again
mov ax,251ch
mov dx,old_seg
push dx
mov dx,old_off
pop ds
int 21h
pop ds
popf
ret
delay endp
code ends
end start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -