スタックを詳細に説明

スタックを説明する前に、私たちは、スタックの感情的な理解を持ってみましょう

スタックを使用するポットをスクラブ、野菜、野菜やその他の準備や洗濯料理に関係なく、私たちは夕食のためにレストランに行くと、ちょうどアラカルト(アプリケーションを発行)、給与、および(使用)を食べて、供給及び左:このようモップアップ作業として、彼の利点は高速ですが、自由度が小さいです。
ヒープ:食べ物を食べるのが好きDIY、あまりにも面倒、より自分の好みに合わせて、かつ自由度が大きいような。

そして、途中のプロセス・スタックの定義と関数呼び出しスタックを見て

非常に役立つ関数呼び出しを明確にするために、黄色の入札スタックで定義された点を覚えておいてください。

スタック定義:スタックが特定のAの特定の記憶領域又はレジスタ内のデータ構造です。スタックのデータ構造が配列のデータ項目です。固定された一端がデータ項目を挿入および削除する(スタック(トップ)の上面と呼ぶ)のみ一端、他端(スタックの最上部)が浮いています 、要素間に配置されている原理「最後のアウト」アクセスに厳密に従って、そのような要素は、(後方スタックの)それらの除去後にスタックの上部に一枚ずつ取り出されなければなりません。したがってスタックアドレスは常に未満またはスタックのベース・アドレスに等しいです。

#include <stdio.h>
void __stdcall func(int param1,int param2,int param3)
{
    int var1=param1;
    int var2=param2;
    int var3=param3;
    printf("0x%08x\n",param1); //打印出各个变量的内存地址
    printf("0x%08x\n",param2);
    printf("0x%08x\n\n",param3);
    printf("0x%08x\n",&var1);
    printf("0x%08x\n",&var2);
    printf("0x%08x\n\n",&var3);
    return;
}

int main() {
    func(1,2,3);
    return 0;
}

結果がコンパイルされています。

0x0012ff78
0x0012ff7c
0x0012ff80

0x0012ff68
0x0012ff6c
0x0012ff70
├———————┤<—函数执行时的栈顶(ESP)、低端内存区域
│ …… │
├———————┤
│ var 1 │
├———————┤
│ var 2 │
├———————┤
│ var 3 │
├———————┤
│ RET │
├———————┤<—“__cdecl”函数返回后的栈顶(ESP)
│ parameter 1 │
├———————┤
│ parameter 2 │
├———————┤
│ parameter 3 │
├———————┤<—“__stdcall”函数返回后的栈顶(ESP)
│ …… │
├———————┤<—栈底(基地址 EBP)、高端内存区域

ステップ1:スタックに三右から順番パラメータは、、を押し、「PARAM2を」初回「param3」を左に、そして最終的には「パラメータ1」に圧入します。
ステップ2:関数の戻りアドレス(RET)を押し嵌め、次いでアドレスにジャンプする機能を実行します。
ステップ3:数を減算スタックの最上位(ESP)は、メモリ空間はローカル変数に割り当てられる、実施形態は、12バイト(ESP = ESP-3 * 4、各変数INT 4バイト)を減算することによって得られる、それらローカル変数のメモリ空間を初期化します。

最後に、特定のスタックの違いを見て

両方の定義:

  1. スタック地区:自動変数。機能時、ストレージ装置の機能は、スタック上のローカル変数を作成することができ、自動的に機能実行の終了時に解放コンパイラによってメモリセル関数のパラメータ、ローカル変数、などのスタック。
  2. ヒープ(無料店舗):呼び出し側がメモリを割り当てるために(例えばmalloc関数の新しいCとして、またはC ++で)実行されている、あなたはいつでもメモリの割り当てと配布のサイズを決定することができ、利用者自身がときにメモリを解放する責任があります( )を使用し、無料または削除など。すべてのヒープは匿名で、そのためには、名前によってアクセスが、唯一のポインタを介してアクセスすることはできません

具体的な違い:
適用します。
スタック領域:システムによって自動的に割り当てられます。例えば、ローカル変数INT Bの関数宣言において、スタックにおけるB自動的にオープンスペース。
ヒープ:アプリケーションプログラマのニーズと、(c)に、malloc関数の大きさを示す
ような、P =(CHAR *)のmalloc(AS、 10); p自体がスタックしていることに留意されたいです。
に応じたシステムの応用:
スタック領域:限り、残りのスタック空間がアプリケーション空間よりも大きいように、システムは、それ以外の場合は、スタックオーバーフロー例外が報告され、プログラムメモリを提供します。
ヒープ:まず、オペレーティングシステムは、空きメモリアドレスのリンクリストがあることを知っている必要があり、システムがアプリケーション・プロセスを受信したときに、記録され、ノードその後、最初のスペースは、アプリケーション・ヒープ・スペース・ノードよりも大きい見つけ、リンクリストをトラバースします無料のノードから削除するには、リストをリンク、およびプログラムへのノードの空間分布は、加えて、ほとんどのシステムで、これはこのレコードサイズのために割り当てられた第1のメモリ空間に対処しますので、コードを削除することこのリリースのメモリ空間を補正するために声明。さらに、以降のノードを見つけるために、スタックのサイズの大きさは、システムが自動的にバックフリーリストの余剰部分に、必ずしもアプリケーションに正確に等しくありません。
アプリケーションのサイズを制限:
スタック領域はWindowsでは、スタックは下位アドレスデータ構造に展開されていることは、メモリの連続した領域ですこの手段スタックアドレスの最大容量ことと、所定のシステムをスタックと、スタック・サイズが2M(一部言う1Mは、要するに、それはコンパイル時定数で決定される)であり、WINDOWSで、良好です宇宙アプリケーションがスタックに残っているスペースを超えたとき、あなたはオーバーフローするように求められます。したがって、より少ないスペースがスタックから得られます。
ヒープヒープは、高アドレスデータ構造に拡張された連続したメモリ領域ではありませんシステムは不連続な性質のアドレスを格納するための空きメモリのリンクリストで、リストのトラバース方向が低いから高いアドレスにあるためです。ヒープサイズは、コンピュータシステムの有効仮想メモリによって制限されます。したがって、空間利用可能なヒープより柔軟な、比較的大きいです。
アプリケーションの効率の比較:
スタック領域:スタックは自動的に高速なシステムによって割り当てられます。しかし、プログラマが制御することはできません。
ヒープ:、新しい通常よりゆっくりと、メモリの断片化が発生しやすいが、使用することが最も便利で割り当てられたヒープメモリ。また、WINDOWSで、最良の方法は、メモリを割り当てるVirtualAllocのを使用することで、彼はヒープではありませんでした、またそれは、それが最も不便を使用しましたが、高速メモリは、プロセスのアドレス空間に直接スタックに予約されています。しかし、スピードだけでなく、最も柔軟性。
ヒープとスタックメモリの内容は以下のとおりです。
スタック領域関数呼出し、スタックへの最初の主要な機能(関数呼び出し文で実行文)アドレス内の次の命令であり、ほとんどのCコンパイラでは、様々なパラメータの関数です。容器は、右から左引数にスタックにプッシュし、ローカル変数の関数です。静的変数はにプッシュされていないことに注意してください。この関数呼び出し、ローカル変数の先入れ先出しスタックメモリの先頭アドレスへの最後のスタックポインタ点のパラメータの終了後、即ち次の命令の主な機能は、プログラムは、この時点から実行を継続します
ヒープ:サイズは1バイトでストアヒープ内の一般ヘッドスタック。ヒーププログラマの手配の具体的な内容。
アクセス効率の比較:
スタック領域:CHAR * S2 =「bbbbbbbbbbbbbbbbb」 ; bbbbbbbbbbbは、 コンパイル時に決定され、最初に読み込まれるEDXポインタ値、EDXにしたがっては明らかに遅く、文字を読んで。しかし、文字列(例えば、スタック)ポインタ点よりスタック上のアレイ。
ヒープ:文字S1 [] =「aaaaaaaaaaaaaaa 」; aaaaaaaaaaa 実行時の割り当てでは、置き文字列要素を直接読み込むレジスタCL、見かけ上速く読み。

リリース元の2件の記事 ウォンの賞賛0 ビュー97

おすすめ

転載: blog.csdn.net/ky_zhang/article/details/104721902