2017-04-23 6 views
0

私はNASMアセンブリプログラムでstrstr C関数を使用しようとしていますが、正しく印刷されないようです。私はこれを複数試してみましたが、printfや '(null)'に返される空白行を取得すると、Cからポインタ値を返す方法を誤解している可能性があります。私はなぜ私は正しい戻り値を印刷することができないように私を埋めるのを助けることができますか?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'。私はあなたが源泉がそこにあることを意味すると確信しています。また、 'myString'とは何ですか?表示したコードでは、たとえそれを使用していても定義されていません。なぜ、単に「プッシュeax」だけではないのですか? –

+0

私は 'int 0x80'を使用しているので、LinuxまたはmacOSと仮定します。次回は、あなたの質問にこの情報を追加してください。 Windowsでは、状況は少し異なります。 –

答えて

1

主な問題は、検索文字列に0x0Aです。これは、文字列の一部です。終端するヌルの前のすべてがその一部です。文字列内のC-style escape sequencesはアセンブラで解決されないため、別途リストする必要があります。 「テスト\ n」はstrstrによって見つかりません。 0x0Aを削除し、strstrに検索文字列が見つかります。

コーディーグレイが言及したように、mov ebp, esiのブロックは変わっています。おそらく、慣用句mov ebp, espを意味しています。さらに、この例では不要です。また、myString-push eaxの直接間接です。

printfは、まず出力をバッファに書き込みます。 int 80hシステムコールを使用してプログラムを終了します。この呼び出しは、printf-bufferを含むプロセスのすべてを破壊します。したがって、バッファは出力されません。問題を解決する方法は2つあります。

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を定義したセクション.dataをコピーしませんでした。読み込まれた入力コマンドライン引数から0x0Aのようなヌルターミネータを削除する方法はありますか?したがって、str2を使用する代わりに、strstrにstr1のコマンド行引数文字列を検索させます。私はそれをやろうとしましたが、コマンドラインでargを読み込むと、文字列の最後に終端文字があります。 –

+0

@SamIvanecky:0x0Aはヌルターミネータではなく、改行(=改行)です。ヌルターミネータは0x00であり、文字列の一部ではなく、C関数に文字列の終わりを通知し、削除しないでください。コマンドラインへのアクセスが失敗する多くの理由が考えられます。対応する[MCVE](http://stackoverflow.com/help/mcve)で新しい質問をする必要があります。 – rkhb

関連する問題