2017-04-23 35 views
0

我想在NASM彙編程序中使用strstr C函數,但似乎無法使其正確打印出來。我嘗試了多種變化,但我想我可能會誤解NASM如何從C返回指針值,因爲我在printf或'(null)'中返回空行。爲什麼我無法獲得正確的印刷回報值?有些人可以幫我填補嗎?在NASM中使用strstr()的返回值?

section .data 

    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x0A, 0x00 
    strFmt db "%s",0x0A,0x00 

    global _start 
    extern printf 
    extern strstr 

section .text 

_start: 

    push ebp 
    mov ebp, esi 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    mov dword [myString], eax 

    push dword [myString] 
    push strFmt 
    call printf 
    add esp, 8 

_exit: 
    mov ebx, 0 
    mov eax, 1 
    int 0x80 
+0

這看起來像一個錯字:'mov ebp,esi'。我敢打賭,你的意思是來源於'esp'那裏。另外,什麼是'myString'?即使您使用它,這也未在您所展示的代碼中定義。爲什麼不直接'直接推eax'? –

+0

我看到你使用'int 0x80',所以我認爲這是Linux或macOS。請下次在您的問題中添加此信息。 Windows上的情況稍有不同。 –

回答

1

主要問題是搜索字符串中的0x0A。它是字符串的一部分,因爲終止null之前的所有內容都是它的一部分。它必須單獨列出,因爲C-style escape sequences內部的字符串不會被彙編程序解析。 strstr將不會找到「test \ n」。刪除0x0Astrstr將找到搜索字符串。

正如科迪格雷提到的,與mov ebp, esi塊是奇怪的 - 你可能意味着慣用的mov ebp, esp。而且,這個例子中並不需要。直接與myString -just push eax間接也是多餘的。

printf首先將輸出寫入緩衝區。您通過系統調用int 80h退出程序。這個調用會破壞包括printf緩衝區在內的所有進程。所以緩衝區不會被輸出。有兩種方法來解決這個問題:

1)使用C函數exit而不是系統調用:

section .data 
    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x00 
    strFmt db "%s",0x0A,0x00 

global _start 
extern printf, strstr, exit 

section .text 

_start: 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    push eax 
    push strFmt 
    call printf 
    add esp, 8 

_exit: 
    push 0 
    call exit 

2)調用添加到C函數fflush

section .data 
    str1 db "Here is some text with a word",0x0A,0x00 
    str2 db "text",0x00 
    strFmt db "%s",0x0A,0x00 

global _start 
extern printf, strstr, fflush 

section .text 

_start: 

    push str2 
    push str1 
    call strstr 
    add esp, 8 

    push eax 
    push strFmt 
    call printf 
    add esp, 8 

    push 0 
    call fflush 

_exit: 
    mov ebx, 0 
    mov eax, 1 
    int 0x80 
+0

感謝您的幫助。是的,我的意思是有esp,而不是esi。另外,我錯過了複製我定義myString的section .data。有沒有辦法從讀入的輸入命令行參數中移除像0x0A這樣的空終止符?因此,不是使用str2,而是使用strstr在str1中搜索命令行參數字符串。我試過這樣做,但是當你在命令行中讀取arg時,你會在字符串的末尾得到終止字符。 –

+0

@SamIvanecky:0x0A不是空終止符,而是換行符(=換行符)。空終止符是0x00,不是字符串的一部分,它表示C函數結束字符串,不應該被刪除。可能有很多原因導致您無法訪問命令行。您應該使用相應的[MCVE](http://stackoverflow.com/help/mcve)提出一個新問題。 – rkhb