12

popアセンブリで実際に何をするのか混乱しています。popPUSHed を最後にスタックに移動するか(つまりMOV、最後の要素PUSHed の後に値がある場合は適用されません)、スタックの最後にある値をポップします (したがって、 と の両方に適用されますMOV) PUSH、またはスタックポインタが指す値をポップしますか? 次のコードを検討してください。

push $4
mov $5, -4(%esp)
add $4, %esp (esp pointing to an unknown value)
pop %ebp

したがって、このコードでは、ポップさebpれる値は 4、5、または が指す未知の値になりespますか?

4

2 に答える 2

21

PUSH <src>する:

 ESP := ESP-4  ; for x86; -8 for x64
 MEMORY[ESP]:=<operandvalue>

POP <dst>する:

 <operandtarget>:=MEMORY[ESP];
 ESP:=ESP+4    ; for x86; +8 for x64

このように疑似コードで説明を書き留めておくと、機械語の命令が何をするのかを理解しやすくなります。Intel のリファレンス マニュアルには、このような疑似コードがたくさんあります。時間と労力をかけてそれらを入手し、詳細を自分で読んでください。(例: HTML 抽出https://www.felixcloutier.com/x86/pushおよびhttps://www.felixcloutier.com/x86/pop )

あなたの具体的な質問について: あなたのストアの$5into-4(%esp)は有効な機械命令であり、プロセッサはそれを問題なく実行しますが、実際には非常に危険なプログラミングです。プロセッサがその命令の直後にトラップまたは割り込みを行うと、プロセッサの状態は (通常は) 「スタックの一番上」に保存され、値が上書きされます。割り込みは非同期に発生するため、まれに $5 が失われるという動作が見られます。これにより、プログラムのデバッグが非常に困難になります。

「add $4」は、ESP をpush 命令の前の場所に戻します。したがって、オプションの1つとして提案したように「不明」であることを除いて、ebpにポップされた値については何も言えません。

Windows のユーザー空間であっても ESP より下の書き込みが安全でない理由の詳細については、Raymond Chen のブログを参照してください。(割り込みはユーザー空間スタックを非同期に使用しませんが、いくつかのことは可能です。) Windows 以外では、POSIX シグナル ハンドラーはユーザー空間 ESP の下のスペースを踏むことができます。(x86-64 System V を除いて、ABI は安全に使用できる RSP より 128 バイト下の「レッド ゾーン」を定義します。)

于 2014-09-24T21:01:03.983 に答える