先言
一个简单的汇编实验:通过8086汇编代码,基本实现计算机模拟电子琴的效果。特点在于通过图像模式绘制出了电子琴,且渲染出了按压效果。
实验目标
1.按下按键1-8时,依次发出8个音调;
2.按CTRL+C退出程序;
3.1-8按键的音调频率表(524、588、660、698、784、880、988、1048)
4.保存输入音调并自动播放
5. 实现菜单界面交互
6. 绘制电子琴图形和动态展示
结果展示
源码附录
DATAS SEGMENT
SENTEN01 DB '-----PROGRAM START-----',0DH,0AH,'$';
SENTEN02 DB 'INPUT ctrl+c TO EXIT',0DH,0AH,'$';
SENTEN03 DB 'INPUT esc TO RETURN',0DH,0AH,'$';
SENTEN04 DB 'INPUT number TO ENTER',0DH,0AH,'$';
SENTEN05 DB '1.PLAY',0DH,0AH,'$';
SENTEN06 DB '2.SAVE',0DH,0AH,'$';
SENTEN07 DB '3.REVIEW',0DH,0AH,'$';
SENTEN08 DB '4.OPERATION',0DH,0AH,'$';
FREQ DW 524,588,660,698,784,880,988,1048;
CONTENT DB 2000 DUP(?)
MODE DB 00H;
NUM DB 00H;
DATAS ENDS
;两只老虎
; 12311231345345565431565431151151
STACKS SEGMENT
STA DB 200 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
;---------------
;draw 宏定义,绘制矩形
DRAW MACRO SX,SY,EX,EY,COL
LOCAL DRAW_NEXT
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AH,0CH
MOV AL,COL;12功能写像素
MOV BH,0;页码0防止偏移
MOV CX,SX
MOV DX,SY
DRAW_NEXT:
INT 10H;中断画点
INC CX
;INC CX
CMP CX,EX
JNE DRAW_NEXT;画完该行
MOV CX,SX
INC DX
;INC DX
CMP DX,EY
JNE DRAW_NEXT
POP AX
POP BX
POP CX
POP DX
ENDM
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,STACKS
MOV SS,AX
MOV SP,200
CALL MENU
CALL EXIT
;---------------
;EXIT 退出程序
EXIT PROC NEAR
MOV AH,4CH
INT 21H
RET
EXIT ENDP
;---------------
;INPUT 键盘输入字符
INPUT PROC NEAR
PUT:
MOV AH,00H
INT 16H;input char to al
RET
INPUT ENDP
;---------------
;KEY 对AL字符输入值执行不同的操作
KEY PROC NEAR
MOV NUM,AL
CMP AL,'1'
JE ONE
CMP AL,'2'
JE TOW
CMP AL,'3'
JE THREE
CMP AL,'4'
JE FOUR
CMP AL,'5'
JE FIVE
CMP AL,'6'
JE SIX
CMP AL,'7'
JE SEVEN
CMP AL,'8'
JE EIGHT
RET;不是预期按键直接返回
ONE:
MOV BX,FREQ
JMP SOUND
TOW:
MOV BX,FREQ+2
JMP SOUND
THREE:
MOV BX,FREQ+4
JMP SOUND
FOUR:
MOV BX,FREQ+6
JMP SOUND
FIVE:
MOV BX,FREQ+8
JMP SOUND
SIX:
MOV BX,FREQ+10
JMP SOUND
SEVEN:
MOV BX,FREQ+12
JMP SOUND
EIGHT:
MOV BX,FREQ+14
JMP SOUND
SOUND:
CALL WORK
RET
KEY ENDP
;---------------
;WORK 对bx储存的freq开始播放
WORK PROC NEAR
MOV DX,0012H
MOV AX,34DEH
DIV BX;计算输入freq初值
PUSH AX
MOV AL,1011011B;设置8253控制端口工作状态
OUT 43H,AL
POP AX
OUT 42H,AL
MOV AL,AH
OUT 42H,AL;输入发声freq值
IN AL,61H
OR AL,00000011B;打开扬声器
OUT 61H,AL
wait1:
CALL DELAY
in al,60h
test al,80h;检测键盘按压情况
jz wait1
IN AL,61H
AND AL,11111100B;关闭发声器
OUT 61H,AL
RET
WORK ENDP
;---------------
;DELAY 对当前状态的一段时间维持,如持续发声
DELAY PROC NEAR
PUSH CX
PUSH AX
CALL PRESS
MOV AL,MODE
CMP AL,0
JE MODE1
MOV AX,070H
JMP FOR1
MODE1:
MOV AX,010H
FOR1:
MOV CX,0FFFH
FOR2:
LOOP FOR2
DEC AX
JNZ FOR1
CALL LOOSEN;将琴键复原
POP AX
POP CX
RET
DELAY ENDP
;---------------
;SAVE 记录输入音频
SAVE PROC NEAR
CALL CLEAR
MOV SI,02H
MOV BX,OFFSET CONTENT
FOR3:
MOV AH,01H
INT 21H
CMP AL,27
JE QUIT;退出编码格式
MOV [BX+SI],AL
INC SI;连续地址的存储
JMP FOR3
QUIT:
DEC SI
DEC SI
MOV [BX],SI;储存音频长度在前两位
RET
SAVE ENDP
;---------------
;REVIEW 播放储存音频
REVIEW PROC NEAR
CALL CLEAR
CALL INIT
MOV BX,OFFSET CONTENT
MOV CX,[BX]
MOV SI,02H
FOR4:
MOV AL,[BX+SI]
PUSH BX
CALL KEY
POP BX
INC SI
LOOP FOR4
RET
REVIEW ENDP
ClEAR PROC NEAR
MOV AX,12H
INT 10H;
RET
CLEAR ENDP
;---------------
;PLAY 实时弹奏音乐
PLAY PROC NEAR
CALL CLEAR
CALL INIT
PUT1:
CALL INPUT
CMP AL,27
JE RETURN
CALL KEY
JMP PUT1
RETURN:
RET
PLAY ENDP
;---------------
;OPERATION 介绍操作说明
OPERATION PROC NEAR
CALL CLEAR
MOV DX,OFFSET SENTEN02
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN03
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN04
MOV AH,09H
INT 21H
PUT2:
CALL INPUT
CMP AL,27
JNE PUT2
RET
OPERATION ENDP
;---------------
;MENU 菜单界面,选择功能
MENU PROC NEAR
CHOOSE:
CALL CLEAR
MOV DX,OFFSET SENTEN01
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN05
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN06
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN07
MOV AH,09H
INT 21H
MOV DX,OFFSET SENTEN08
MOV AH,09H
INT 21H
CALL INPUT
CMP AL,'1'
JE P
CMP AL,'2'
JE S
CMP AL,'3'
JE R
CMP AL,'4'
JE O
CMP AL,03H
JE E
JMP CHOOSE
RET
P:
MOV MODE,00H
CALL PLAY
JMP CHOOSE
S:
CALL SAVE
JMP CHOOSE
R:
MOV MODE,01H
CALL REVIEW
JMP CHOOSE
E:
CALL EXIT
O: CALL OPERATION
JMP CHOOSE
RET
MENU ENDP
;---------------
;INIT 绘制钢琴图像
INIT PROC NEAR
MOV AH,00H
MOV AL,0DH
INT 10H
MOV AH,0BH
MOV BH,0
MOV BL,00H
INT 10H
;绘制白色琴键 和灰色底盘
DRAW 40,40,290,100,08H;
DRAW 50,50,70,90,0FH
DRAW 80,50,100,90,0FH;
DRAW 110,50,130,90,0FH;
DRAW 140,50,160,90,0FH;
DRAW 170,50,190,90,0FH;
DRAW 200,50,220,90,0FH;
DRAW 230,50,250,90,0FH;
DRAW 260,50,280,90,0FH;
;绘制琴键底部银色阴影
DRAW 50,90,70,93,07H;
DRAW 80,90,100,93,07H;
DRAW 110,90,130,93,07H;
DRAW 140,90,160,93,07H;
DRAW 170,90,190,93,07H;
DRAW 200,90,220,93,07H;
DRAW 230,90,250,93,07H;
DRAW 260,90,280,93,07H;
;绘制黑色琴键
DRAW 70,50,80,80,00H;
DRAW 100,50,110,80,00H;
DRAW 130,50,140,80,00H;
DRAW 160,50,170,80,00H;
DRAW 190,50,200,80,00H;
DRAW 220,50,230,80,00H;
DRAW 250,50,260,80,00H;
;绘制绿色开关
DRAW 42,42,50,45,0ah
;绘制银色边框修饰
DRAW 40,39,291,40,07H;
DRAW 39,39,40,100,07H;
DRAW 39,100,290,101,07H;
DRAW 290,39,291,101,07H;
RET
INIT ENDP
;---------------
;PRESS 展示按压效果
PRESS PROC NEAR
CMP NUM,'1'
JE SETONE
CMP NUM,'2'
JE SETTOW
CMP NUM,'3'
JE SETTHREE
CMP NUM,'4'
JE SETFOUR
CMP NUM,'5'
JE SETFIVE
CMP NUM,'6'
JE SETSIX
CMP NUM,'7'
JE SETSEVEN
CMP NUM,'8'
JE SETEIGHT
RET
SETONE:DRAW 50,90,70,93,0FH;
RET
SETTOW:DRAW 80,90,100,93,0FH;
RET
SETTHREE:DRAW 110,90,130,93,0FH;
RET
SETFOUR:DRAW 140,90,160,93,0FH;
RET
SETFIVE:DRAW 170,90,190,93,0FH;
RET
SETSIX:DRAW 200,90,220,93,0FH;
RET
SETSEVEN:DRAW 230,90,250,93,0FH;
RET
SETEIGHT:DRAW 260,90,280,93,0FH;
RET
PRESS ENDP
;---------------
;LOOSEN 展示松开琴键效果
LOOSEN PROC NEAR
CMP NUM,'1'
JE SETONE1
CMP NUM,'2'
JE SETTOW1
CMP NUM,'3'
JE SETTHREE1
CMP NUM,'4'
JE SETFOUR1
CMP NUM,'5'
JE SETFIVE1
CMP NUM,'6'
JE SETSIX1
CMP NUM,'7'
JE SETSEVEN1
CMP NUM,'8'
JE SETEIGHT1
RET
SETONE1:DRAW 50,90,70,93,07H
RET
SETTOW1:DRAW 80,90,100,93,07H;
RET
SETTHREE1:DRAW 110,90,130,93,07H;
RET
SETFOUR1:DRAW 140,90,160,93,07H;
RET
SETFIVE1:DRAW 170,90,190,93,07H;
RET
SETSIX1:DRAW 200,90,220,93,07H;
RET
SETSEVEN1:DRAW 230,90,250,93,07H;
RET
SETEIGHT1:DRAW 260,90,280,93,07H;
RET
LOOSEN ENDP
CODES ENDS
END START
参考清单
汇编课设(电子钢琴:源代码)_电子琴汇编代码-CSDN博客(看样子已经收费了)