[英]Loop/Input Logic Flow Issue (NASM x86 Assembly)
我在下面有一個程序試圖從用戶那里獲取輸入並重復相同的字符串,直到用戶再次輸入它。 (這是個人學習項目)
但是,我在使其正確執行方面有一些嚴重的困難。 在此處的過去帖子中,您可以看到其他用戶就此問題提供的輸入,雙關語。
%include "system.inc"
section .data
greet: db 'Hello!', 0Ah, 'Please enter a word or character:', 0Ah
greetL: equ $-greet ;length of string
inform: db 'I will now repeat this until you type it back to me.', 0Ah
informL: equ $-inform
finish: db 'Good bye!', 0Ah
finishL: equ $-finish
newline: db 0Ah
newlineL: equ $-newline
section .bss
input: resb 40 ;first input buffer
check: resb 40 ;second input buffer
section .text
global _start
_start:
greeting:
mov eax, 4
mov ebx, 1
mov ecx, greet
mov edx, greetL
sys.write
getword:
mov eax, 3
mov ebx, 0
mov ecx, input
mov edx, 40
sys.read
sub eax, 1 ;remove the newline
push eax ;store length for later
instruct:
mov eax, 4
mov ebx, 1
mov ecx, inform
mov edx, informL
sys.write
pop edx ;pop length into edx
mov ecx, edx ;copy into ecx
push ecx ;store ecx again (needed multiple times)
mov eax, 4
mov ebx, 1
mov ecx, input
sys.write
mov eax, 4 ;print newline
mov ebx, 1
mov ecx, newline
mov edx, newlineL
sys.write
mov eax, 3 ;get the user's word
mov ebx, 0
mov ecx, check
mov edx, 40
sys.read
sub eax, 1
push eax
xor eax, eax
checker:
pop ecx ;length of check
pop ebx ;length of input
mov edx, ebx ;copy
cmp ebx, ecx ;see if input was the same as before
jne loop ;if not the same go to input again
mov ebx, check
mov ecx, input
secondcheck:
mov dl, [ebx]
cmp dl, [ecx]
jne loop
inc ebx
inc ecx
dec eax
jnz secondcheck
jmp done
loop:
pop edx
mov ecx, edx
push ecx
mov eax, 4
mov ebx, 1
mov ecx, check
sys.write ;repeat the word
mov eax, 4
mov ebx, 1
mov ecx, newline
mov edx, newlineL
sys.write
mov eax, 3 ;replace new input with old
mov ebx, 0
mov ecx, check
mov edx, 40
sys.read
jmp checker
done:
mov eax, 1
mov ebx, 0
sys.exit
示例輸出將產生:
Hello!
Please enter a word or character:
INPUT: Nick
I will now repeat this until you type it back to me.
Nick
INPUT: Nick
N
INPUT: Nick
INPUT: Nick
這種情況一直持續到它死亡為止。 關於這個問題的任何想法?
謝謝。
instruct
在堆棧上留下兩個項目,第一次循環時由checker
使用。 但是,對於再次繞過循環的情況,它們不會被替換。 這是您的代碼中最基本的問題(可能還有其他問題)。
您可以通過運行調試器並觀察堆棧指針esp
來找到它; 但只能通過查看代碼就可以看出 - 如果除了堆棧操作和分支之外你把所有內容都拿出來,你可以清楚地看到checker
- > loop
- >返回checker
路徑彈出三個項目但只推送一個:
greeting:
...
getword:
...
push eax ;store length for later
instruct:
...
pop edx ;pop length into edx
...
push ecx ;store ecx again (needed multiple times)
...
push eax
checker:
pop ecx ;length of check
pop ebx ;length of input
...
jne loop ;if not the same go to input again
...
secondcheck:
...
jne loop
...
jnz secondcheck
jmp done
loop:
pop edx
...
push ecx
...
jmp checker
done:
...
有更好的方法可以保留長期存在的變量,而不是像使用push
和pop
那樣在堆棧中將它們pop
。
將它們保存在數據部分(您已經擁有的.bss
將是合適的)而不是堆棧中。
在堆棧上分配一些空間,並直接在那里加載/存儲它們。 例如sub esp, 8
保留兩個32位字,然后訪問[esp]
和[esp+4]
。 (堆棧應該與32位邊界對齊,因此始終保留4個字節的倍數。)記住在使用完畢后add esp, 8
。
(這些基本上相當於C編譯器將分別對全局(或static
)變量和局部變量執行的操作。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.