📄 delay.asm
字号:
data SEGMENT
ASSUME DS:DATA
freq DW 0,4552,4029,3617,3415 ;定义各频率对应的N值
DW 3042,2710,2415,2279
note DB 3,2,1,2,3,3,3,2,2,2 ;定义乐谱,-1表示结束
DB 3,5,5,3,2,1,2,3,3,3
DB 3,2,2,3,2,1,-1
dl_time DB 4,4,4,4,4,4,8,4,4,8 ;定义各音符的节拍
DB 4,4,8,4,4,4,4,4,4,4
DB 4,4,4,4,4,8
data ENDS
code SEGMENT
ASSUME CS:CODE
main PROC FAR
MOV AX,DATA ;取数据段地址
MOV DS,AX ;设定DS
MOV AL,10110110B ;初始化8253 TIMER 2
OUT 43H,AL ;设定音符数组下标初值
MOV BX,0
play:
MOV AL,NOTE[BX] ;取一个音符
MOV AH,DL_TIME[BX] ;取对应节拍
INC BX ;数组指针加1
PUSH BX ;保存音符指针
PUSH AX ;保存节拍值
CBW ;将音符转为16位
SHL AX,1 ;音符值×2,计算频率表指针
MOV BX,AX ;频率表指针置入BX
MOV AX,FREQ[BX] ;取出对应频率值
OUT 42H,AL ;输出频率值
MOV AL,AH
OUT 42H,AL
IN AL,61H ;开启定时器
OR AL,3
OUT 61H,AL
MOV AH,0 ;取时钟计数值
INT 1AH
POP AX ;取回节拍值
MOV AL,AH
CBW ;节拍值转为16位
ADD AX,DX ;加上当前时钟计数值,得到计数终值
MOV BX,AX ;计数终值置入BX
delay:
MOV AH,0
INT 1AH ;取时钟计数值
CMP BX,DX ;到终值吗?
JNZ DELAY ;未到,继续延时
IN AL,61H ;延时结束,关闭定时器
AND AL,0FCH
OUT 61H,AL
POP BX ;取回音符数组指针
CMP NOTE[BX],-1 ;演奏结束吗?
JNZ PLAY ;未结束,继续演奏下一个音符
MOV AH,4CH ;选择DOS API的4CH功能
INT 21H ;终止进程,返回DOS
main ENDP
code ENDS
END MAIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -