2012-02-27 7 views
0

GCCでコンパイルされたいくつかのx86アセンブリコードを逆アセンブルしています。

はすぐに関数を呼び出す前に、私が持っている:プッシュした後

$esp = 0xffffdbcc 

:(pushが前であっても)を与えると呼ばれる関数の最初の行にブレークポイントを設定

$esp = 0xffffdbd0 

$esp = 0xffffdbc8 

なぜ$espがlそれ?理論的には、関数に移動するだけでスタックポインタが変更されることはなく、pushの後に変更されますか?どうしたの?

私はアライメントと関係があり、何とか何らかの形でアライメントが行われていることを、callpushアセンブリの説明書で確認しています。しかしそれは推測です。何も思いつきません。

誰かが知っていることができますか?

+1

x86命令セットについて学んでください。インテルとAMDのCPUマニュアルには、各命令の内容についての詳細な説明が含まれています。 –

+0

うん。 。 。私はそれに取り組んでいます。 – imallett

答えて

4

CALL命令を実行すると、CALLの直後の命令のアドレスがスタックにプッシュされます。これは、RET命令を実行すると、プログラムは正しいアドレスにジャンプして命令を実行し続けることができるようになります。このアドレスをスタックにプッシュすると、CALLがネストされ、それぞれRETの正しいアドレスに戻っても問題はありません。単にスタックを変更してはならない機能に行く、理論的

0xffffdbd0 - 0xffffdbcc = 0x4 
+0

ありがとう、みなさん、とても助かりました! – imallett

3

命令call命令は、ターゲット位置にジャンプする前に、最初の命令のアドレスをスタックにプッシュします。このようにして、retは、関数が復帰した後のどこに行くかを知っています。

2

あなた仮定

:この以来

は、32ビットシステムであり、4つのバイトがスタックにプッシュします ポインタ

は間違っています。関数へ行くということは、スタックポインタを変更することになります。特に、スタックポインタを返します。 x86(とほぼすべての他のアーチ)の「プッシュ」は、常にスタックポインタを暗黙的にデクリメントし、プッシュされる値を格納することを意味します。

+0

ebpがespに設定され、espが減る前に、シンボル(関数呼び出しをjmpのように呼び出すことを考えていた)に行き、関数のアドレスに行くことを意味しました。コール関数が単なるjmp以上のことをするようになりました。ありがとう。 – imallett