簡體   English   中英

循環/輸入邏輯流程問題(NASM x86匯編)

[英]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:
    ...

有更好的方法可以保留長期存在的變量,而不是像使用pushpop那樣在堆棧中將它們pop

  1. 將它們保存在數據部分(您已經擁有的.bss將是合適的)而不是堆棧中。

  2. 在堆棧上分配一些空間,並直接在那里加載/存儲它們。 例如sub esp, 8保留兩個32位字,然后訪問[esp][esp+4] (堆棧應該與32位邊界對齊,因此始終保留4個字節的倍數。)記住在使用完畢后add esp, 8

(這些基本上相當於C編譯器將分別對全局(或static )變量和局部變量執行的操作。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM