1

私は組み立てが初めてで、何が起こっているのか本当にわかりません。

プログラムの 5 つのフェーズへの正しい入力を見つけることによって、爆弾を解除する必要がある宿題を完了しようとしています。

質問に対する答えをオンラインで探してみましたが、探している答えを見つけるために何を検索すればよいかわかりません。

<+0>からまでの以下のコードのすべてを理解していると思います<+35>。cmp 演算子では、 と、レジスタに格納されているもの<+40>を比較するために呼び出されます。比較の時点で、scanf への関数呼び出しがまだ保存されていると思います (間違っていたら訂正してください)。$0x2%eax%eax

gdb を使用することで、scanf 関数が次のように呼び出されたことがわかります。 scanf("%d %d", &x, &y);

では、この場合、正確には何を$0x2参照しており (値 2 だけですか?)、2 つの項目を比較すると何が起こっているのでしょうか?

これはGAS構文だと思います。

   0x0804870a <+0>:     sub    $0x2c,%esp
   0x0804870d <+3>:     lea    0x1c(%esp),%eax
   0x08048711 <+7>:     mov    %eax,0xc(%esp)
   0x08048715 <+11>:    lea    0x18(%esp),%eax
   0x08048719 <+15>:    mov    %eax,0x8(%esp)
   0x0804871d <+19>:    movl   $0x8048baa,0x4(%esp)
   0x08048725 <+27>:    mov    0x804b040,%eax
   0x0804872a <+32>:    mov    %eax,(%esp)
   0x0804872d <+35>:    call   0x8048480 <__isoc99_fscanf@plt>
   0x08048732 <+40>:    cmp    $0x2,%eax
   0x08048735 <+43>:    je     0x8048743 <phase_1_of_5+57>
   0x08048737 <+45>:    movl   $0x1,(%esp)
   0x0804873e <+52>:    call   0x80486ef <explode>
   0x08048743 <+57>:    mov    0x18(%esp),%eax
   0x08048747 <+61>:    mov    %eax,%edx
   0x08048749 <+63>:    shl    $0x5,%edx
   0x0804874c <+66>:    add    %edx,%eax
   0x0804874e <+68>:    cmp    0x1c(%esp),%eax
   0x08048752 <+72>:    je     0x8048760 <phase_1_of_5+86>
   0x08048754 <+74>:    movl   $0x1,(%esp)
   0x0804875b <+81>:    call   0x80486ef <explode>
   0x08048760 <+86>:    add    $0x2c,%esp
   0x08048763 <+89>:    ret
4

1 に答える 1

1

JE および関連する指示との一般的な混同。コードが何をしているかを視覚化するために、デバッガーを入手することをお勧めします。

cmp は内部的に減算しますが、実際には eax == 2 かどうかをチェックします。eax == 2 JE (JUMP IF EQUAL) の場合、ジャンプするため、EIP レジスタ (次に実行される命令) は 0x08048743 ("phase_1_of_5+57" のメモリ アドレス) になります。eax != 2 の場合、JE を無視してステップオーバーします。

スポイラーは、自分で練習して再び行き詰まるまで、これを読まないでください。

そこで、http://www.tutorialspoint.com/c_standard_library/c_function_fscanf.htmを調べます。fscanf の機能 戻り値 2 は、2 項の入力が必要であることを意味します。ここで、2 つの用語を入力すると仮定し、今度は JE に従います。

わかります(これが、これを視覚化するためにデバッガーが必要な理由です)

mov    0x18(%esp),%eax
...
cmp    0x1c(%esp),%eax

0x18 == 6th value on the stack
0x1c == 7th value on the stack
safe to assume these are the two input terms.

0x08048743 <+57>:    mov    0x18(%esp),%eax
0x08048747 <+61>:    mov    %eax,%edx
0x08048749 <+63>:    shl    $0x5,%edx
0x0804874c <+66>:    add    %edx,%eax

ここで、爆弾を解除する方法は、最初の項に追加された最初の項の 5 だけ左シフトに入ることであると想定できます。二期へ。

したがって、0 0 はそれを解除する必要があります。

于 2016-02-24T22:20:52.183 に答える