5

nasm コンパイラと ld リンカを使用して、アセンブリ言語で hexdump ユーティリティを作成しました。このプログラムは、任意の入力ファイルの 16 進値をダンプすることになっています。 16バイトのバッファ。コードは

LoadBuff:
    push ebx                 
    push edx
    push eax

    mov eax,3       ;sys_read call      
    mov ebx,0               ;read from standard input
    mov ecx,Buff            ;pass the buffer adress
    mov edx,BuffLen         ;pass the number of bytes to be read at a time
    int 80h                 ;call the linux kernel
    mov ebp,eax
    ;cmp eax,0              ;number of characters read is returned in eax
    ;jz exit                ;if zero character is returned i.e end of iinput file      
                            ;jump to exit

    xor ecx,ecx 
    pop eax
    pop edx
    pop ebx
    ret

行の場合

;cmp eax,0                   
;jz exit                      

ただし、コメントを付けてこれらの行を呼び出し元に含めて、ここではなく呼び出し元で同じ比較を行うと、このプロシージャ セグメント エラーが発生します。

gdb バックトレースが与える

#0  0x00000000 in ?? ()

なぜそのようなことが起こっているのですか?

4

1 に答える 1

1

NASM を使用していますが、Intel スタイルの構文を使用しているか、AT&T スタイルの構文を使用しているかを指定していません。ただし、サンプルコードを見ると、Intel スタイルだと思います。

Intel スタイルの構文では、次のような操作は次のようにmov機能します。

mov <destination>, <source>

つまり、「目的地=源流」の考え方を真似ようとしているのです。AT&T 構文では逆になります。

mov <source>, <destination>

言い換えれば、「ソースを宛先に移動する」を読んでいるかのように、彼らはそれを見ます。

次のコード行を見てください。

mov ebp, eax

mov %ebp, %eaxIntel スタイルの構文を使用している場合 (AT&T スタイルの構文eaxebp. ebpは伝統的に「ベースポインタ」として使用されます...「ポインタ」という単語に注意してください...そしてしばしばそのように使用されます。eax で 0 を取得すると、既存のベース ポインターがヌル ポインターで上書きされます。奇抜なハイジンクが続きます。


ただし、問題はそれだけではありません。さらなる問題はこれです:

jz exit

あなたが投稿したコードのどこにも終了ラベルが表示されないため、手順の外でどこかにジャンプしています(そうしないと、アセンブラーが泣き言を言うでしょう)。その過程で、スタック クリーンアップ コードを渡し、スタックを不明な状態のままにします。基本的に、3 つのレジスタの内容をスタックにプッシュし、他のルーチンが想定していない場所に残しました。

問題は、クリーンアップ コードを飛び越えていることです。手順の開始時に、ebxedxおよびを押していますeax。手順の最後に、それらを逆の順序 ( eaxedxおよびebx) で正しくポップします。これにより、スタックは終了時にエントリ時と同じ状態のままになり、これに依存するコードは期待どおりに実行されるように設定されます。

ただし、それjzはその時点を超えてジャンプするため、どこに行っても、そこにあってはならない 3 つの値がスタックに存在します。クリーンアップ コードを通過するのではなく、クリーンアップ コードにジャンプする必要があります。

一般的なルールは、プロシージャ内でプッシュしたものを常にポップすることです。この規則には (非常に少数の) 例外がありますが、今のところ、注意をそらすほど頻繁には発生しません。

于 2011-05-06T04:15:47.403 に答える