7

組み立ては初めてです。デバッグされている実際のコードとは別に、GDBで計算を実行する方法はありますか?たとえば、Linux IA-32アセンブリ(AT&T構文)を使用して次の手順を実行しています。

   ;$esi is 0xbffff0a8 which refers to 1 after this command. $eax is 2
   0x08048cd5 <+42>:    lea    -0x20(%ebp),%esi

   ;$eax=ebx=2 after this instruction
   0x08048cd8 <+45>:    mov    %ebx,%eax 

   ;$eax equals 2 after this instruction               
   0x08048cda <+47>:    add    -0x4(%esi,%ebx,4),%eax

$ eaxが2になるのがわかりません。gdbで-0x4(%esi、%ebx、4)のような命令を実行して、結果を分析できますか?

私が理解しているように、$ebxに4を掛けて8を算出します。これを$esiに加算して9を算出します。次に-4を減算して5を算出します。次に5を$eaxに加算します。 eaxは2です。

4

1 に答える 1

7

それがあなたが求めているものであるならば、あなたはレジスターを使って式を評価することができます。

gdbprintコマンドはあなたの友達です。

基本的に、ドル記号を前に付けることでレジスターを照会できます。

print $ecx

または式で使用します。

print $esi + $ebx + 4

*演算子(Cのように)を使用してメモリを逆参照できます。

print *$ecx

が指すメモリ位置の内容を出力しecxます。

アセンブリコードを直接入力することはできませんが、式を次のように、より高レベルのものに変換できます。

print $eax - ($esi * $ebx)

また、Cデータ型へのキャストを使用してさまざまな型に変換できます。

print (char)$ecx

の内容をecx文字として出力します。

print *(char**)$ecx

ecxこれは、へのポインタとして解釈されchar*、それを逆参照します。したがって、に含まれるアドレスに文字列の内容が表示されecxます。

ただし、これは氷山の一角にすぎません。gdbは非常に強力なツールです。displayこのコマンドが役立つ場合もあります。基本的にはと同じですが、コードが停止するたびにコマンドprintが繰り返される点が異なります(ブレークポイントで役立ちます)。を使用して、またはマゾヒスティックである場合は、printほとんどのレジスタを調べることができます。info registersinfo all-registers

次を使用して、レジスタの内容を変更することもできますset

set $eax = 20

stepi指示を介して、またはcontinueプログラムを実行します。

PSわからない場合は、ブレークポイントの設定方法などを学びたいと思うでしょう。

于 2012-10-08T01:29:40.800 に答える