2011-11-04 82 views
3

我正在編寫一個程序,以簡單地接受用戶的輸入兩次,然後將結果輸出到標準輸出。我遇到的問題是,當從輸入中斷返回結果時(eax),我將它壓入堆棧以備後用。我再次爲第二個用戶輸入。x86 NASM組件 - 與堆棧有關的問題

我到目前爲止的代碼是:

%include "system.inc" ; used for renaming of interrupts (sys.write and sys.read) 

section .data 
    greet:  db 'Hello!', 0Ah, 'What is your name?', 0Ah 
    greetL:  equ $-greet  ;length of string 
    colorQ:  db 'What is your favorite color?', 0Ah 
    colorL:  equ $-colorQ 
    suprise1: db 'No way ' 
    suprise1L: equ 7 
    comma:  db ', ' 
    commaL:  equ $-comma 
    suprise3: db ' is my favorite color, too!', 0Ah 
    suprise3L: equ $-suprise3 


section .bss 

name: resb 50 
color: resb 50 

section .text 

    global _start 
_start: 


greeting: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, greet 
    mov edx, greetL 
    sys.write 

getname: 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, name 
    mov edx, 50 
    sys.read 

    xor ecx, ecx 
    mov eax, ecx 
    push ecx 

askcolor: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, colorQ 
    mov edx, colorL 
    sys.write 

getcolor: 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, color 
    mov edx, 50 
    sys.read 

    xor ebx, ebx 
    mov ebx, eax 
    push ebx 


thesuprise: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, suprise1 
    mov edx, suprise1L 
    sys.write 

    xor ebx, ebx 
    xor ecx, ecx 
    xor edx, edx  
    pop ecx 
    sub ecx, 1 
    mov edx, ecx 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, name 
    mov edx, edx 
    sys.write 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, comma 
    mov edx, commaL 
    sys.write 

    xor ebx, ebx 
    xor ecx, ecx 
    xor edx, edx 
    pop ebx 
    sub ebx, 1 
    mov edx, ebx 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, color 
    mov edx, edx 
    sys.write 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, suprise3 
    mov edx, suprise3L 
    sys.write 

done: 

    mov eax, 1 
    mov ebx, 0 
    sys.exit 

我得到的嚴重問題間距在輸出中,最有可能的,因爲我是如何處理在EAX返回的值時,我推/彈出它。有什麼辦法可以解決這個問題嗎?我做錯了嗎?

回答

1
greeting: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, greet 
    mov edx, greetL 
    sys.write 

getname: 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, name 
    mov edx, 50 
    sys.read 

我不知道這些sys.writesys.read宏預計爲你做,但有機會,他們調用系統調用與int 0x80之前用正確的值裝載eax,所以你可能不需要自己做。有一個在他們,否則沒有多大意義......

(這不是問題,但; 43分別在32位Linux的x86爲write正確的系統調用號和read

實際問題這裏大概:

xor ecx, ecx 
    mov eax, ecx 
    push ecx 

這看起來錯了:你是異或ecx自身,它設置爲零。然後你將ecx(現在是0)分配給eax(這是系統調用的結果),所以系統調用的結果被拋棄了。然後你將ecx(仍然是0)推入堆棧。

再進一步上,您有:

xor ebx, ebx 
    xor ecx, ecx 
    xor edx, edx  
    pop ecx 
    sub ecx, 1 
    mov edx, ecx 

...這也是奇怪:爲什麼零ecxedxxor說明,當你只是要從別處一對夫婦重新載入進一步的指示?


我想你可能只是有錯誤的方式操作數mov。相反的:

xor ecx, ecx 
    mov eax, ecx 
    push ecx 

...如果你說:

xor ecx, ecx 
    mov ecx, eax 
    push ecx 

....你至少成功地推(從系統調用的返回碼),這是在eax到價值棧,雖然這將是一個簡單得多,只是說:

push eax 

最後:你問的是「名」的問題,和(假設上面它是固定的)將所得長度推到堆棧上。然後你問「顏色」問題,並將結果長度推到堆棧上。

但是,然後使用從堆棧中彈出的第一個值打印「名稱」驚喜,這是從「顏色」問題中保存的長度。 (堆棧是先進先出!)然後,使用「名稱」問題的長度打印「顏色」驚喜。

+0

宏僅使代碼更易讀;他們不會做任何事情,但用另一個詞替換int 80。我還沒有完成閱讀,但它看起來像美麗的幫助! – nmagerko

+0

好的,所以我看到你說的所有評論,但現在我只是修復它們。你的猜測是正確的,我改變了它。以防萬一。我相信,我的問題是進一步下降。爲什麼當我彈出輸入的第一個字符串的長度時,兩個輸入都有問題(帶間距)?部分單詞在第二個中被切碎,第一個單詞後面有一個巨大的空間 – nmagerko

+0

查看更新後的答案。如果你推一個值X然後推另一個值Y,第一個彈出的值將是Y(不是X)。 –

0

感謝馬特和ott。

下面是解:

%include "system.inc" 

section .data 
    greet:  db 'Hello!', 0Ah, 'What is your name?', 0Ah 
    greetL:  equ $-greet  ;length of string 
    colorQ:  db 'What is your favorite color?', 0Ah 
    colorL:  equ $-colorQ 
    suprise1: db 'No way ' 
    suprise1L: equ 7 
    comma:  db ', ' 
    commaL:  equ $-comma 
    suprise3: db ' is my favorite color, too!', 0Ah 
    suprise3L: equ $-suprise3 


section .bss 

name: resb 50 
color: resb 50 

section .text 

    global _start 
_start: 


greeting: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, greet 
    mov edx, greetL 
    sys.write 

getname: 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, name 
    mov edx, 50 
    sys.read 

    sub eax, 1 
    push eax 

askcolor: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, colorQ 
    mov edx, colorL 
    sys.write 

getcolor: 
    mov eax, 3 
    mov ebx, 0 
    mov ecx, color 
    mov edx, 50 
    sys.read 

    sub eax, 1 
    push eax 


thesuprise: 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, suprise1 
    mov edx, suprise1L 
    sys.write 

    xor eax, eax 
    pop eax 
    mov ecx, eax 
    pop eax 
    mov edx, eax 
    push ecx 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, name 
    ;mov edx, edx 
    sys.write 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, comma 
    mov edx, commaL 
    sys.write 

    xor eax, eax 
    pop eax 
    mov edx, eax 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, color 
    ;mov edx, edx 
    sys.write 

    mov eax, 4 
    mov ebx, 1 
    mov ecx, suprise3 
    mov edx, suprise3L 
    sys.write 

done: 

    mov eax, 1 
    mov ebx, 0 
    sys.exit