【问题标题】:Program displays garbage after user hits key用户按键后程序显示垃圾
【发布时间】:2017-02-24 18:00:07
【问题描述】:

我正在尝试在理想模式下使用 8086 汇编和 Turbo Assembler (TASM) 制作钢琴。当我运行时一切都很好,当我单击一个键时会发出声音,但是当我再次单击时,整个屏幕会打印出垃圾数据。

你能看出这个 TASM 代码中的问题吗?

IDEAL
MODEL small
STACK 100h
DATASEG
Welcome db "Welcome! Just Try Clicking those buttons on your keyboard $"

CODESEG
start:
mov ax, @data
mov ds, ax
call printWelcome
jmp loopGetKey

loopGetKey:
call getKey
jmp loopGetKey

exit:
mov ax, 4c00h
int 21h

proc printWelcome
mov dx, offset Welcome
mov ah, 9
int 21h
ret
endp printWelcome

proc getKey
waitForKey:
;Check the status of the keyboard
mov ah, 1
int 16h
jz waitForKey
;read key
mov ah, 0
int 16h
;exit if ESC is pressed
cmp al, 1Bh
je exit
cmp al, 61h
je soundA
cmp al, 73h
je soundS
cmp al, 64h
je soundD
cmp al, 66h
je soundF
cmp al, 67h
je soundG
cmp al, 68h
je soundH
cmp al, 6Ah
je soundJ
cmp al, 6Bh
je soundK
cmp al, 6ch
je soundL
jne @continue

soundA:
push 2280
call makeSound
soundS:
push 2031
call makeSound
soundD:
push 1809
call makeSound
soundF:
push 1715
call makeSound
soundG:
push 1521
call makeSound
soundH:
push 1355
call makeSound
soundJ:
push 1207
call makeSound
soundK:
push 2031
call makeSound
soundL:
push 2031
call makeSound

@continue:

ret 
endp getKey 

proc makeSound
push bp
mov bp, sp
in al, 61h
or al, 00000011b
out 61h, al
mov al, 0b6h
out 43h, al
mov ax, [bp+4]
out 42h, al
mov al, ah
out 42h, al       
call delay
call stopSound
ret 4
endp makeSound

proc stopSound
push ax
in al, 61h
and al, 11111100b
out 61h, al 
pop ax
ret
endp stopSound

proc delay
push cx
push dx
push ax
mov     cx, 0FH
mov     dx, 4240H
mov     ah, 86H
int     15H
pop ax
pop dx
pop cx
ret
endp delay
END start

【问题讨论】:

  • 可能是您在调用 makeSound 之前将 2 个字节压入堆栈,然后在 ret 指令中弹出 4 个字节?你应该学习如何使用debug
  • @Gene:鉴于这是 TASM 代码,我建议尝试使用 Turbo Debugger 代替机器代码监视器。然而,这些决定从所有事物中挑选 8086 来向一无所知的可怜学生说明计算机体系结构原理的虐待狂是谁?

标签: assembly x86 x86-16 dos tasm


【解决方案1】:

看看你的过程叫做'makeSound',它的结尾。
您将 bp 推入堆栈,但没有将其弹出。这是一个很大的错误。
您还使用了“ret 4”而不是 2。它是 2,因为您在调用 proc 之前只按下了一个单词。

结尾应该是这样的:

    pop bp
    ret 2
endp makeSound

我还看到您在某些标签中使用了“@”。您应该使用其中的 2 个 (@@)。 例如:

@@myLabel:
    **code**
    jmp @@myLabel

【讨论】:

  • @roeiedri 即使按照 Ben R 的建议进行更正,您的 piano 也会产生很多噪音,因为当您按 'a' 时它会调用 all 依次发出声音!我认为那些call makeSound 说明最好是jmp makeSound(需要与建议的不同的修改!)
猜你喜欢
  • 2014-03-30
  • 1970-01-01
  • 2013-07-10
  • 2016-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多