2

私はアセンブリ言語が初めてで、バイナリから生成されたアセンブリ ファイルを (gdb で) デコードしようとしています。次のコードを理解できません (これは新しい関数の始まりです)。私は x64 マシンを使用し%rdiており、6 桁 (入力) を保持しています。ですから、それは0 1 2 3 4 5)

   400e79:       55                      push   %rbp
   400e7a:       48 89 e5                mov    %rsp,%rbp
   400e7d:       48 83 ec 30             sub    $0x30,%rsp
   400e81:       48 89 7d d8             mov    %rdi,-0x28(%rbp)
   400e85:       48 8d 75 e0             lea    -0x20(%rbp),%rsi
   400e89:       48 8b 7d d8             mov    -0x28(%rbp),%rdi

もしよろしければ、私が考えていることをお見せしたいと思います。

400e79: したがって、関数を開始するときに、古いベース ポインターをスタックにプッシュします。したがって、スタックは次のようになります。

 RETURN ADDRESS
 old %rbp value  <--- %rsp

400e7a: スタックは次のようになります。

 RETURN ADDRESS
 old %rbp value <---- %rsp, %rbp

400e7d: スタックは次のようになります。

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 ----empty----  <---%rsp

400e81: ここからのものは、私を本当に混乱させているものです. %rdi( 0 1 2 3 4 5) 内を に移動し-0x28(%rbp)ます。したがって、スタックは次のようになります。

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty----
 0 1 2 3 4 5
 ----empty----  <---%rsp

-0x28(%rbp)ただし、gdb で実行して何が入っているかを確認しようとすると、期待どおりにx/s $rbp-0x28取得されませんが、 . これを正しく実行していますか?0 1 2 3 4 5"\020C"

400e85:スタック:

 RETURN ADDRESS
 old %rbp value  <----%rbp
 ----empty----
 ----empty----
 ----empty----
 ----empty---- <--- %rsi
 0 1 2 3 4 5
 ----empty----  <---%rsp

400e89:私はこれをまったく理解していません。先ほどやったのにmov %rdi,-0x28(%rbp)、なぜ今やっているのmov -0x28(%rbp),%rdiですか? これの繰り返しではないですか?

どうもありがとう!これは本当に長いことを知っています。私を助けてくれてありがとう!

4

1 に答える 1

2

あなたの分析は正しいです。

実行時に奇妙な結果が得られるのx/s $rbp-0x28は、文字列をレジスタに入れることができないためです。レジスタに含まれる値は、その文字列へのポインタである可能性が最も高いため、それを読み取るには別のレベルの間接化が必要です。私はこれがうまくいくと信じています:

p/x *(char**)($rbp-0x28)
x/s $

無駄な負荷に関しては、最適化せずにコンパイルされたコードによく見られます。コンパイラは、現在のレジスタ値を考慮せずに、各行をアセンブリに盲目的に変換します。複数のレジスタを介して単一の値を元のレジスタに戻すコードを見てきました。

于 2012-10-26T05:10:42.510 に答える