真の解関数呼び出し規約

はじめに:この記事は慣例が理解できる呼び出しベースのコンパイルせずに人々を許可するように設計され、そして最も重要なことは、関数呼び出し時にシステムスタック上で何が起こっているかを理解することである関数の呼び出し規約を理解するためには、これはここでの焦点です。

関数呼び出し規約とは何ですか

この関数は、関数が呼び出されたときに、関数のパラメータは、呼び出される関数に渡され、戻り値は呼び出し元の関数に返されることを意味する規則を呼び出します。規則を呼び出すと、関数パラメータの受け渡しがどのようで、誰によって記述することであるスタックのバランス、そしてもちろん、戻り値の。 - "Baiduの百科事典"

呼び出し規約の関数は、文字通り、これは、関数が呼び出されたときに従うべきプロトコルである、そして誰がそれに従うために起こっている、仕様を踏襲すべきですか?コンパイラ。呼び出し規約いわゆる関数は、関数を指すように、スタックに注文パラメータを転送制御を含むイベントの場合、一連呼ばれます。そのうち最も重要なのは、メッセージの変更スタックは、システムスタックは、レコードの関数です。私たちも理解は関数が呼び出されたときに、システムがスタックを変更する方法である関数呼び出し規則で絞り込むことができます。


追加の知識(基本スキップ可能があります)

スタック

リニアテーブルのスタック。スタック(スタックプッシュ)とスタック端と呼ばれる削除(ポップポップ)操作の一端のみを挿入することができ、もう一方の端の反対側のそれ、それが任意の操作を許可しない、スタックの底部と呼ばれています。

アナログ線状の配列を想像する、要素一つずつ、および動作の期間が制限され、他方の端部は、任意の操作を行うことができません。あなたは何を期待できますか?、これはと思うかもしれないより多くの利益を考えるためのイニシアチブを参照してください。

スタックの一端開放は、スタックは下のセクションを囲まれて:はい、私たちはなるように、以下のスタック空間を描くことができます。質問があるので、スタックの最下部には、我々は簡単にそれを見ることができることは明らかであるが、スタックそれの上?どのように我々は、スタックの先頭を定義していますか?私たちは彼らの前任者を解決するための問題は、彼らがトップ位置マーク・スタック・ポインタ、およびプッシュとポップ操作と動的更新と先頭ポインタを使用していました。
ここに画像を挿入説明
ここに画像を挿入説明
明らかに、これらの2つの図は、グラフィカルにスタックが何であるかを表し、およびスタックがプッシュ操作されたときに、トップは更新する方法である、とあなたが類推を開くことができます。

プッシュ:
1スタックの上部を調整する:スタック更新中トップは、素子積層体を製造するために一つのユニット、予約領域の一の単位を、シフトアップ
2.PUSHを:TOPポインタは、準備作業、要素スタックを行い、予約された空間を充填、スタックは完了です。

POP:
1.POP:ポップスタックのスタック要素のトップを指します。
スタックを更新し、トップダウン:スタックの先頭を調整します。2.。

まとめ:以上のことから、どのように我々は、ダイナミックスタック領域を変更するには、スタックの形状を決定するか、次のような結論を得ることができます。

最後アウト現象が生じるのみ(上部)動作することができ、スタック内のスタックの最上位として、1
スタックの上部とスタックは同じでスタックの下部に空である場合2。
3.push操作をポップし、動的に(上記で与えられた)スタックを更新する方法。
4.スタックおよびスタックの底部は、スタック空間の有効期間について決定されます。

システムスタックのコンパイルとの関係

アセンブリ言語命令とレジスタは、スタックの存在と関連します。次の例ではアセンブリはx86。

命令:

スタックにプッシュ
要素のスタックのPOP現在のスタック点b、aとbが中に配置されている
コール2当量の指示:プッシュEIP - > JMP [目的関数アドレス]
RETN当ポップEIP

RETNコールと関連プログラムの実施を制御するために送信されたEIPを、動作しなければなりません。

登録:

EBP:スタックポインタの下
ESP:スタックポインタ、最上位に対応します。
EIP:次の(次のものではなく、現在の)フラグ命令は機械語命令を実行またはコンパイルされなければなりません。EIPは、プログラムの実行の流れを制御することであるべき次のステップを実行する方法をCPUに伝えるために位置を指していることは非常に重要です!EIPは、通常の状況下での動きのシーケンスであり、前記送信制御の上下面、分岐ジャンプ中の高レベルの言語と同様EIPのアドレスを変更するためのイニシアチブを取ること、です。

その他の関連レジスタ:ESI、EDI、EBX

下、EBP、およびESPを持つシステムはスタック領域のいくつかについて決定することができます。
我々は、スタックフレームを呼び出し、システムスタックは、関数呼び出しの機能の変化のシリーズを記録するために使用され、それぞれが独自のスタック空間のいくつかのユニークな機能を有している、前に、このスタック空間は、システムスタックの一部であると述べています。実際には、この考えはまた、より良い他の分野にも反映、例えば、プロセスが作成されるたびに、プロセスの仮想アドレス空間の一部だけがあるだろう、それはスタックフレームを確立する関数呼び出しのようなものです。
ビューのマクロ観点から、スタックフレームにシステムスタックは、基本単位として考えることができます。マイクロは、私はそこにどのようなスタックフレームを知っておく必要があります。
各スタックフレームの内容が同じではありませんが、幸いスタックフレームが従うべき軌道を確立することが、各スタックフレームには、以下の内容があります。

(また、発信者の発信者として知られている)1.保存生成機能副機能(発信者呼び出し先)端で生成関数生成機能とサイト復元に呼制御のための重要な情報。
2.機能情報。

今、私はそれが問題で、以下の罰金を言うだろうしません理解していません。


関数呼び出し規約の詳細

私は理解CDECL後CDECLはケースのように分析し、デフォルトのC言語の呼び出し規約、他の呼び出し規約と同じことになります。

高レベルの言語:
私はビューの集合場所からデモを使用するには、呼び出し規約の関数を何が起こったのかをまとめました。ここで私は、上記の主生成機能を説明するためのサブルーチンとしてfuncをしています。最後に、私たちは、この例では拡張子によってルールが含まれています。
ここに画像を挿入説明
編集レベル:

私が見て、スタックの組み合わせを描き、次のシステムの内容を組み合わせるようにしてください。注脳は、独自のダイナミックな操作を補完します。
ここに画像を挿入説明

ここに画像を挿入説明
どこオペレーティングシステムスタックの影響を見ました。のは、最初の赤いボックスを無視してみましょう、それは今主な機能は、フレーム確立を積層する方法、スペースの変更機能funcをスタックする方法母親を呼び出し、第二の赤いボックス、に焦点を当てています。

このディレクティブを懸念コールFUNC。私たちは、その前にプッシュ一連の動作を発見し、コンテンツのプッシュがFUNCに渡された三つの主要なパラメータの生成機能です。明らかに、彼らのスタック順序を確認することは困難ではない右から左にあります。これは、我々は拡張子それによって、我々はちょうどcdecl呼び出し規約ことができ、見るものでしょうか?これは、修正することができますが、正しいことではない証明しました。

スタック順序への関数のパラメータは、右から左へです。

コールCALLコマンドは、コントロールは、サブルーチンに転送されます。ここでプッシュEIPを暗示。

ここでは、方法を変更するメインサブルーチンコールスタックスペースFUNC機能の生成を見て:
ここに画像を挿入説明
我々は唯一の赤いボックスに焦点を当てる必要がありますが、私は1つずつ説明します。
1.ローカル変数の新しいスタックフレーム、オープンスペースの作成、保存された情報生成機能部。

どのように保存された生成機能情報を理解するには?まず、一つだけの名前で、このようなESPまたはEBPレジスタのか!私はあなたが勉強していない場合はコンパイルが不思議に思うかもしれませんことを知って、どのような地獄は、レジスタ・スタックはありますか?私は、スタックは、データ・レジスタで、実際には、これは、レジスタ・スタックではありません、またでした!なぜこれを行いますか?私は、アセンブラは非常に必要で、動揺になります読んでいませんか?確かに、いくつかの本当に必要はありませんが、いくつかは、私たちが動作しない場合は、そのようなスタック情報の生成機能底として、保管しなければならないが、直接EBPデータにどのように我々が生成リトリーブ機能を終了したスタックFUNCの下、FUNCコールに更新され、スタックの底部は、スタックの一番下には、データ生成機能は、スタックフレームが失われることはありません!私たちは、すべてのコード2つの変数のデータ交換を書いて、我々は通常、一時的な変数と一つの変数のためのデータを保持するためにtmpになり、データの損失を防ぐために、真実です!我々はEBPを回復するために登録などの機能にデータを保存するために使用する必要がありますので、一言で言えば、以降のレジスタに対応する機能の実装が、唯一のものです。

スタック情報生成機能スタックのプッシュEBP底
のMOV EBPは、スタックポインタのESP底は、ESP = EBP、我々は空のスタックに相当上に述べたこの時点で、更新されます。
サブESP、ローカル変数の0C0Hオープンスペースは、
3つのレジスタ店舗情報生成機能、及び保存EBPの共感を押します。

2及び3:関数呼び出し終了フェーズ、生成機能データ回復、破壊FUNC関数のスタックフレーム(ESPスタック空間の一部は、手段、上記限り減少としてESP ESP部が、そう消去しないデータフェイル、あまり効果的ですしかし)スタックスペースの有効範囲外で、それを投げ、これらの非有効なデータ空間は、スタック領域の活動で覆われます。また、ESPとEBP関与する2〜3赤枠の一部として、これはスタック領域の保護機構が異常チェックはそれらを無視です。

コールスタックホルダーがEIPレジスタに返されたときに、コントロールが親関数に転送され、実行さここポップEIPをRET EIPデータ生成機能と同等です。(どのような送信制御、私が言うすべての操作をプッシュポップ、彼らはこの無知な力を見ていない、とスタックセグメントの上に追加の知識を確認するために見て、再び上記のリターンを理解していませんでした。)

最後の質問に答える時間です。私は、スタックフレームがEBPとESPの組成物の各機能、私はメインESPはスタックの次FUNC底ユニット、それをポイントしていないはず描いた、システム・スタック図との間の領域であると言う前に、きっとあなたはこの記事を読んで持って、それを発見しましたか?FUNCスタックフレームのパラメータは、それに起因するのはなぜ?実際、前述のように、私たちは今、私は理由を説明しましょう、でなければなりません。(以下は、個人的な理解と観察です)

私たちは、スタックフレームのFUNCを見て、funcはスタックフレームの最新で、このFUNCの上部に何のスタックフレームが存在しない、我々は、スタックの最上部と完璧なアコードFUNCメインスタックの間で、その区別を見つけます。この観察に基づいて、我々は最初のポイントに来ます。
私たちは、スタックフレームの一番下を見てみましょう。スタックの一番下にあるフレーム、およびスタックフレームミアンないの下部にFUNC任意の追加のパラメータが、私は誰もが混乱これはどこだと思います。私はこの主なパラメータを書いていないので、引数が存在しない主な理由!三つのパラメータと楽しみがあります!それは、その後明らかにパラメータがサブルーチン・スタック・フレームに分割されている関数の引数を持っているかどうかの決定は、スタックの底のサブルーチンスタックフレーム内のサブ関数パラメータの下であるが、非常に合理的です。

そして最後の後、主な機能はすぐに実行され0CH、ESPアドオンを呼び出します。このディレクティブの目的は、FUNCパラメータを破壊するために、スタックのバランスをとることです。バランスの取れた命令の呼び出し先スタックとは対照的に、我々は、発信者のスタックのバランスを呼び出すアカウントは、同様のセマンティック機能で実行され、キャンセルFUNCのパラメータの主な機能です。

私は詳細にデモ関数funcのスタックフレームを作成するプロセスを説明してきたとさえ破壊され、そのうちのいくつかは、説明の不要な部分を避けるために、動作を説明するために、適切な説明が必要。このプロセスは、呼び出し規則の主な内容である、他の機能を拡張することができますが、他の異なる呼び出し規約の座席の違いがあります。

私はあなたが書く前にメインESP、メインEBPは唯一の理解を容易にするために、どのようなペイント、およびいくつかの古いEBPを書き、上記のスタックはスタック情報生成機能の下部にある一番下の機能を意図しました。

関数呼び出し規約の種類

x86プラットフォーム

CDECL

デフォルトのC言語の呼び出し規則。
パラメータスタック順序:左へ右の
スタックバランス:呼び出し側(生成機能)

STDCALL

大会の呼び出しのWin32 API
左へ右:パラメータのスタック順序
スタック残高:呼び出し先(サブルーチン)

fastcall

コール効率効率的な
レジスタに右から左へ、Linuxプラットフォームの前にレジスタへの最初の2つのパラメータWindowsプラットフォーム四つのパラメータ、およびシャドウ空間スペースを保持します:スタック順序の上にパラメータを
スタックのバランスを:呼び出し側(サブルーチン)

x64プラットフォーム

fastcall

この統一されたプラットフォームのx64呼び出し規約を使用します。
右から左へ、Linuxプラットフォームの前にレジスタへの最初の4つのパラメータWindowsプラットフォームレジスタに6つのパラメータ、およびシャドウ空間スペースを保持します:スタック順序の上にパラメータ
スタックバランス:呼び出し側(生成機能)

公開された19元の記事 ウォンの賞賛2 ビュー2527

おすすめ

転載: blog.csdn.net/SC_king/article/details/105314981