汇编程序 问题..

pengcao89 2010-12-05 07:11:57
dispmsg macro message ;用来调用显示字符串的宏,来源:书本P141
mov dx,offset message
mov ah,9
int 21h
endm


.model small
.stack
.data

;显示音乐菜单的字符串
msgmenu db'************************************** ',0dh,0ah
db'* The music menu is that: * ',0dh,0ah
db'* * ',0dh,0ah
db'* 1:Mary Had a little Lamb * ',0dh,0ah ;玛丽有只小羊羔
db'* 2:Christmas ring * ',0dh,0ah ;圣诞铃声
db'* 3:Little Starlet * ',0dh,0ah ;小星星
db'* 4:Little bee * ',0dh,0ah ;小蜜蜂
db'************************************** ',0dh,0ah,'$'
;音乐播放时,提示的字符
msgdoing db 0dh,0ah,0dh,0ah
db 0dh,0ah,' Now,playing the music which you chose ^_^ please waiting...'
db 0dh,0ah,0dh,0ah,'$'

;提示选择乐曲
msgchoose db 0dh,0ah,'Input number(1~4) to choose the music you want[q to exit!],input:','$'

;提示输入字符错误
msgerror db 0dh,0ah,0dh,0ah,0dh,0ah,'!!! -_- you input a wrong number!!!',0dh,0ah
db 'please try to choose from 1 to 4 again!,[q to exit],input:','$'

;以下对应为各乐曲的频率表和节拍时间表
merry_frequency dw 330,294,262,294,3 dup(330),3 dup(294),330,392,392
dw 330,294,262,294,4 dup(330),294,294,330,294,262,0 ;最后一个0控制结束
merry_time dw 6 dup(25*400),50*400,2 dup(25*400,25*400,50*400),12 dup(25*400),100*400

christ_frequency dw 7 dup(330),392,262,294,330,4 dup(349),2 dup(330),330,294,294,262,294,392
dw 7 dup(330),392,262,294,330,4 dup(349),2 dup(330),392,392,349,294,262,0
christ_time dw 2 dup(25*400,25*400,50*400),4 dup(25*400),100*400,2 dup(25*400,25*400,50*400)
dw 4 dup(25*400),2 dup(50*400),2 dup(25*400,25*400,50*400)
dw 4 dup(25*400),100*400,2 dup(25*400,25*400,50*400),4 dup(25*400),100*400

star_frequency dw 262,262,392,392,440,440,392,349,349,330,330,294,294,262
dw 2 dup(392,392,349,349,330,330,294)
dw 262,262,392,392,440,440,392,349,349,330,330,294,294,262,0
star_time dw 3 dup(6 dup(25*400),50*400,6 dup(25*400),50*400)

bee_frequency dw 392,330,330,349,294,294,262,294,330,349,4 dup(392),330,330,349,294,294
dw 262,330,392,392,3 dup(330),5 dup(294),330,349,5 dup(330),349,392
dw 392,330,330,349,294,294,262,330,392,392,262,0
bee_time dw 2 dup(25*400,25*400,50*400),4 dup(25*400),3 dup(25*400,25*400,50*400)
dw 3 dup(6 dup(25*400),50*400)
dw 2 dup(25*400,25*400,50*400),4 dup(25*400),100*400


table dw music1,music2,music3,music4 ;取得各个标号的偏移地址

.code
.startup

;主程序
startmain: dispmsg msgmenu
dispmsg msgchoose ;提示菜单及输入数字

inputagain: mov ah,1 ;等待按键
int 21h
cmp al,'q' ;输入是否q,是则退出
je game_over
cmp al,'1' ;数字<1?
jb doagain
cmp al,'4' ;数字>4?
ja doagain
and ax,000fh ;将ASCII码转换成数字,以便后面指向table表里对应的地址
dec ax ;减1,对应地址
shl ax,1 ;相当于ax*2,因为table里的相邻偏移地址是2
mov bx,ax
jmp table[bx] ;(段内)间接转移:IP<--[table+bx]跳到table里面对应的程序段

game_over: .exit 0

;以下为子程序、分支程序定义处

;***************输入错误时处理的程序[提示:再次输入]********************
doagain:dispmsg msgerror
jmp inputagain


;**********************以下对应为各乐曲的处理程序************************
music1: dispmsg msgdoing ;输入为1时,唱Mary Had a little Lamb的处理程序
mov si,offset merry_frequency
mov bp,offset merry_time
again1: mov di,[si]
cmp di,0 ;0用于判断是否结束歌曲
je startmain
mov bx,[bp]
call speaker
add si,2 ;取下一频率值
add bp,2 ;取下一时间节拍值
jmp again1
;输入为2时,唱'圣诞歌'的处理程序
music2: dispmsg msgdoing
mov si,offset christ_frequency
mov bp,offset christ_time
again2: mov di,[si]
cmp di,0
je startmain
mov bx,[bp]
call speaker
add si,2
add bp,2
jmp again2
;输入为3时,唱'小星星'的处理程序
music3: dispmsg msgdoing
mov si,offset star_frequency
mov bp,offset star_time
again3: mov di,[si]
cmp di,0
je startmain
mov bx,[bp]
call speaker
add si,2
add bp,2
jmp again3
;输入为4时,唱'小蜜蜂'的处理程序
music4: dispmsg msgdoing
mov si,offset bee_frequency
mov bp,offset bee_time
again4: mov di,[si]
cmp di,0
je startmain
mov bx,[bp]
call speaker
add si,2
add bp,2
jmp again4



;***********************音乐处理子程序*************************
speaker proc
push ax
push bx
push cx
push dx
push di
mov al,0b6h ;向计数器写控制字
out 43h,al ;方式3、双字节写和二进制计数方式写到控制口
mov dx,12h ;设置被除数
mov ax,533h
div di ;其商ax为预置值
out 42h,al ;先送LSB
mov al,ah
out 42h,al ;后送MSB
in al,61h ;读端口原值
mov ah,al
or al,03h
out 61h,al ;接通扬声器

wait1: mov cx,28010 ;设循环次数为8ff0h
delay1: loop delay1
dec bx ;循环持续bx次,即传进来的节拍时间
jnz wait1

mov al,ah ;写回61h端口值,关闭扬声器
out 61h,al
pop di
pop dx
pop cx
pop bx
pop ax
ret
speaker endp
end


源代码 如上..
系统:win7 旗舰32位
工具:记事本+masm.exe+link.exe+debug.com
出现了 如下错误
music.asm(61):error A2105:Expected:instructioon or direction
music.asm(122):error A2053:Jump out of range by 15 bytes
music.asm(134):error A2053:Jump out of range by 49 bytes


改程序的功能是 实现播放音乐..
...全文
120 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
shzhfu 2010-12-05
  • 打赏
  • 举报
回复
简化模式的程序有些记不住了,不知“.startup”有什么问题。

后两个错误是“je startmain”引起的。je等条件转移要求目标地址距转移语句前后不超过128字节(实际是向上不超128和向下不超127)。你的程序中,标号startmain所在语句,距离je startmain这句已超过了128个字节。由于无条件转移的范围可以是-32768到+32767,所以可将
cmp di,0
je startmain
mov bx,[bp]
改为
cmp di,0
jne goon
jmp startmain
goon:mov bx,[bp]

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧