私はasmで多くを扱い、GDBでレジスタとメモリを調べているCの本を読んでいます。 問題は、まったく同じソースをコンパイルして逆アセンブルすると(実際には本のCDに含まれているソースファイルを使用して)、アセンブリの説明は本の内容とかなり異なって見えます。 本書では、Intel Flavoredアセンブリを使用しており、gdbに "set disassembly intel"を置いていますので、そうではありません。命令は異なる順序で、いくつかはすべて一緒に異なっており、いくつかの違いがあります。例えばgdbの奇妙な結果
は、本の中でMOV命令は、EIPレジスタにある:変数iが0の初期化に対応
(gdb) x/i $eip
mov DWORD PTR[ebp-4], 0x0
、forループで(I = 0、I < 10、I ++
(gdb) x/i $eip
mov DWORD PTR[esp+0x1c], 0x0
予告それは別のレジスを参照しています:私はこれを参照してください)実行;)
しかし、同じ場所にブレークポイントと私のGDBコンソール、中(メインを破る設定すべて一緒に - espの代わりにebp 私はespの値をチェックすると、それは0x1c自体です。しかし、0x1cやesp + 0x1cにあるものを調べると、私はそれらのアドレスを見ることができないことがわかります
この本の説明にあるように、 ebp、ebp-4などのトレイルに続き、ebpレジスタで何も起こっていないようです。
この本は2008年に書かれたので、私はできませんgccやgdbのバージョンを変更すると、その変更の重要な部分が導入されることになってしまいます(あるいはやりましたか?)可能性があります。コンパイラの最適化や、 ?
ありがとうございます。
編集:Strange。私はそれぞれの提案を試みたが、何も働かなかった。それから、私はrm a.outを実行して新しく再コンパイルしましたが、今は正常に動作します(指示は本とは異なりますが、本のアドレスに対応するアドレスを調べることができます。正確に同じasmである必要はありません、それはちょうどそれも簡単になります!) あなたのすべての助けと提案をもう一度感謝します。
ありがとうございました。本はgccでコンパイルする(私はバージョンを確認し、qeustionを更新する必要があります)、Linuxを実行している私は32ビットのIntelを使用しています。この本はUbuntuをベースにしています(バージョンを確認する必要があります)。最新のArchをインストールしています。 私は同じアーキテクチャと同じコンパイラ(gcc)でマシンコードが同じではないと思いますか? どちらの方法でも、値が私が調べることのできないアドレスに初期化されていることがわかり、$ esp(つまりスタックポインタ)によって参照されているということも変わってしまいます。 – speakingcode
いいえ、理由は同じではありません。 '-O0'や' -march = i386'で遊ぶことができます。しかし、それが全く違うことは驚くべきことではありません。 –