2017-02-24 42 views
2

我試圖在理想模式下使用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 
+1

會不會是你推到堆棧2個字節調用makeSound,然後在'ret'指令彈出4之前?你應該學習如何使用'debug'。 – Gene

+2

@Gene:鑑於這是TASM代碼,我建議使用Turbo Debugger代替機器代碼監視器。儘管如此,這些虐待狂是誰決定選擇所有的東西來向貧窮的不知情的學生說明計算機體系結構的原理? – doynax

+0

[Asm 8060 program doest print in console]可能重複(http://stackoverflow.com/questions/42231958/asm-8060-program-doest-print-in-console) –

回答

2

看看你的過程叫'makeSound',它的結束。
您將bp推送到堆棧,但未將其彈回。這是一個很大的錯誤。
您還使用了「ret 4」而不是2.它是2,因爲您在調用proc之前只推送了一個單詞。

最終應該看起來像:

pop bp 
    ret 2 
endp makeSound 

我也看到,你用「@」在你的一些標籤。你應該使用其中的2個(@@)。 例如:

@@myLabel: 
    **code** 
    jmp @@myLabel 
+0

非常感謝你! –

+1

@roeiedri即使Ben R提出了更正,你的*鋼琴*會產生很多噪音,因爲當你按下'a'時,它會依次調用全部**聲音!我認爲這些'調用makeSound'指令最好是'jmp makeSound'(需要與建議的不同修改!) –