@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
一
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;************************
DATA SEGMENT
msg DB 0DH,0AH,'[ 1 2 3 4 5 6 7 q] 9 :exit'
;DB 0DH,0AH,' [ q w e r t y u ]'
; DB 0DH,0AH,'_________________'
; DB 0DH,0AH,'9: EXIT'
DB 0DH,0AH,'_________________','$'
;********音调******后面用到-1判断音乐播是否放完
sound_0 DW -1
sound_11 DW 441,-1
sound_12 DW 495,-1
sound_13 DW 556,-1
sound_14 DW 589,-1
sound_15 DW 661,-1
sound_16 DW 742,-1
sound_17 DW 833,-1
sound_1 DW 882,-1
sound_2 DW 990,-1
sound_3 DW 1112,-1
sound_4 DW 1178,-1
sound_5 DW 1322,-1
sound_6 DW 1484,-1
sound_7 DW 1655,-1
time DW 25
DATA ENDS
;************************
STACK SEGMENT
Db 200 DUP ('STACK')
STACK ENDS
;***********************
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START:
MOV AX,DATA
MOV DS,AX
MOV aH,0
MOV AL,00
INT 10H
;*****定义一个宏*****
SHOW MACRO b
LEA DX,b
MOV AH,9
INT 21H
ENDM
;********一个声音宏********
onesound macro soundis,jumpis,letteris
CMP AL,letteris
JNZ jumpis
LEA SI,soundis
LEA BP,DS:time
CALL MUSIC
JMP input
ENDM
show msg
INPUT: MOV AH,01H
INT 21H
CMP AL,'9'
jnz go
mov ah,4ch
int 21h
go: onesound sound_11,a0,'q'
a0: onesound sound_12,b0,'w'
b0: onesound sound_13,c0,'e'
c0: onesound sound_14,d0,'r'
d0: onesound sound_15,e0,'t'
e0: onesound sound_16,f0,'y'
f0: onesound sound_17,g0,'u'
g0: onesound sound_1,h0,'1'
h0: onesound sound_2,i0,'2'
i0: onesound sound_3,j0,'3'
j0: onesound sound_4,k0,'4'
k0: onesound sound_5,l0,'5'
l0: onesound sound_6,m0,'6'
m0: onesound sound_7,n0,'7'
n0: onesound sound_0,o0,al
o0: jmp input
;********************发声
GENSOUND PROC NEAR
;-------------
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
;--------------
MOV AL,0B6H
OUT 43H,AL
MOV DX,12H
MOV AX,348ch
DIV DI
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL
WAIT1: MOV CX,3314
call waitf
DELAY1: DEC BX
JNZ WAIT1
MOV AL,AH
OUT 61H,AL
;----------------
POP DI
POP DX
POP CX
POP BX
POP AX
;-------------------
RET
GENSOUND ENDP
;**************************
waitf proc near
push ax
waitf1:
in al,61h
and al,10h
cmp al,ah
je waitf1
mov ah,al
loop waitf1
pop ax
ret
waitf endp
;************************
MUSIC PROC NEAR
PUSH DS
SUB AX,AX
PUSH AX
FREG: MOV DI,[SI]
CMP DI,-1;音乐是否放完?
JE END_MUS
MOV BX,DS:[BP]
CALL GENSOUND
ADD SI,2
ADD BP,2
JMP FREG
END_MUS:
RET
MUSIC ENDP
CODE ENDS
;**********************
END START
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
二
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; 按键说明:
; 1、不输入任何数字,直接按回车键,可结束程序,返回操作系统
; 2、每次最多能够输入N(本程序,N=8)个数字(1~8)
; 3、不足8位数字的,按回车结束输入
; 本程序在MASMPlus 1.2集成环境下通过编译,经过调试,运行正确。
Code Segment
Assume CS:Code,DS:Code
CR EQU 000DH
LF EQU 000AH
; -------------------------------------
; 功能:显示指定地址(Str_Addr)的字符串
; 入口:
; Str_Addr=字符串地址(要求在数据段)
; 用法: Output Str_Addr
; 用法举例:Output PromptStr
Output MACRO Str_Addr
lea dx,Str_Addr
mov ah,9
int 21h
EndM
; -------------------------------------
; 功能:输出一个字符
; 入口:dl=要显示的字符
Output_Chr proc Near
push ax
mov ah,02h
int 21h
pop ax
ret
Output_Chr endp
; -------------------------------------
; 功能:输出回车换行
Output_CTLF proc Near
push ax
push dx
mov ah,02h
mov dl,0dh
int 21h
mov dl,0ah
int 21h
pop dx
pop ax
ret
Output_CTLF endp
; -------------------------------------
; Subroutine 延时指定的时钟嘀嗒数
; 入口:
; Didas=时钟嘀嗒数(1秒钟约嘀嗒18.2次,10秒钟嘀嗒182次。若延时不是秒的10数次倍,误差稍微大点)
Delay Proc Near
push dx
push cx
xor ax,ax
int 1ah
mov Times,dx
mov Times[2],cx
Read_Time: xor ax,ax
int 1ah
sub dx,Times
sbb cx,Times[2]
cmp dx,Didas
jb Read_Time
pop cx
pop dx
ret
Times dw 0,0
Delay EndP
; -----------------------------------------
; 功能:从键盘输入N位数字
; 入口:N=数字位数;di=保存输入的数字首地址
; 出口:cx=实际接收的数字位数
Input_Digit Proc Near
cld
mov cx,N
@@Input: mov ah,1
int 21h
cmp al,CR
jz @@Return
cmp al,'1'
jb @@Input
cmp al,'8'
ja @@Input
stosb
loop @@Input
@@Return: mov ax,N
sub ax,cx
xchg ax,cx
ret
Input_Digit EndP
; -----------------------------------------
; 入口参数
; SI=声音频率地址
; CX=时间
Music Proc Near
in al,61h
push ax
or al,3
out 61h,al ;接通扬声器
push cx
push dx
push si
mov al,0b6h
out 43h,al
mov dx,12h
mov ax,348ch
div word ptr [si]
out 42h,al
mov al,ah
out 42h,al
in al,61h
mov ah,al
or al,3
out 61h,al
mov cx,3314
push ax
@@Waitf1: in al,61h
and al,10h
cmp al,ah
jz @@Waitf1
mov ah,al
loop @@Waitf1
pop ax
call Delay ;延时
mov al,ah
out 61h,al ;关闭扬声器
pop si
pop dx
pop cx
pop ax
out 61h,al
ret
Music EndP
; -----------------------------------------
Didas equ 18 ;延时(时钟嘀嗒次数)
frequency dw 262,294,330,349,392,440,492,524 ;频率值
; dw 441,495,556,589,661,742,833 ;从其它音乐程序抄来的频率值
; dw 882,990,1112,1178,1322,1484,1655 ;同上行
N equ 8
PromptStr db 'Please Enter ',N or 30h,' digitals(1-8): $'
Number db N dup(?)
Press_Key db CR,LF,CR,LF,'Press any key to exit...$'
; -----------------------------------------
Start: push cs
pop ds
push cs
pop es ;使数据段、附加段与代码段同段
Input_Str: Output PromptStr ;提示输入N位数字
lea di,Number ;数字保存地址
call Input_Digit ;从键盘接收数字
call Output_CTLF ;输出一个回车、换行
call Output_CTLF ;输出一个回车、换行
jcxz Exit_Proc
lea bx,Number ;数字保存地址
Sound: push cx
push bx
mov dl,[bx] ;读入一个数字
call Output_Chr ;屏幕显示这个数字
and dl,0fh
dec dl
shl dl,1
mov bl,dl
mov dl,0eh
call Output_Chr ;显示一个音乐符号
mov dl,20h
call Output_Chr ;显示一个空格
lea si,frequency[bx] ;对应的频率值地址
call Music ;激活扬声器,使之发出指定频率、指定时长的声音
pop bx
inc bx ;增1,处理下一个音符
pop cx
loop Sound
call Output_CTLF ;输出一个回车、换行
call Output_CTLF ;输出一个回车、换行
jmp Input_Str
; -------------------------------------
Exit_Proc: Output Press_Key ;提示操作完成,按任意键结束程序
mov ah,1
int 21h
mov ah,4ch ;结束程序
int 21h
Score_Table: ;学生成绩存储区
Code ENDS
END Start ;编译到此结束 DATAS SEGMENT
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START