C言語・C++におけるメモリ領域
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/05/22 07:15 UTC 版)
「バッファオーバーラン」の記事における「C言語・C++におけるメモリ領域」の解説
スタックベースのバッファオーバーフローについて説明するためにプロセスのメモリ利用方法を復習する。オペレーティングシステム (OS) は各ユーザプロセスに仮想アドレス空間を割り振り、WindowsやLinuxなどのOSでは上位のアドレスをカーネルが使うカーネル空間とし、残りをユーザプロセス自身が用いるユーザ空間とする。カーネル空間はユーザプロセスがアクセスする事はできず、通常のプログラミングでは意識する事はない。 C言語やC++で書かれたプログラムの場合、ユーザ空間をさらに分割する。これらの言語で書かれたプログラムでは、仮想アドレスの最低位の箇所から順にプログラムの実行コードを置くコード領域(テキスト領域とも)、初期化された静的変数・大域変数を置くデータ領域、初期化されていない静的変数・大域変数を置くbss領域、malloc等で動的に確保されたメモリを置く(可変サイズの)ヒープ領域を確保する。(なおデータ領域とbss領域を合わせて静的領域という)。 一方、ユーザ空間における仮想アドレスの最高位の箇所は関数のコールスタックを保存する(可変サイズの)スタック領域として用いられる。 最低位 … 最高位 コード領域 静的領域 ヒープ領域(高位に向かって成長→) … スタック領域(←低位に向かって成長) データ領域 bss領域 スタック領域はプロセス中で呼ばれる関数のコールスタックを格納する領域で、コールスタック中の各関数のデータ(スタックフレームという)を並べて格納している。プロセス中で関数fが関数gを呼び出した場合、コールスタックは以下のようになる: 低位アドレス … 高位アドレス … gのスタックフレーム fのスタックフレーム … … gの処理に必要な一時的な情報 gの局所変数 gのSFP gのリターンアドレス gの引数の値 fの処理に必要な一時的な情報 … … プロセスで現在実行中の関数のスタックフレームの位置を覚えるためにプロセッサによって用いられるのがフレームポインタ(=x86ではebp)で具体的には(現在実行中の関数がgであれば)gのSFPのアドレスを指している。SFPは関数呼び出し時に呼び出し元の関数のフレームポインタのアドレスを覚えるための領域で、fがgを呼び出した際、スタックフレームの値(=fのSFPのアドレス)をgのSFPに格納する。なお、SPFは「Saved Frame Pointer」の略で日本語訳は「退避されたフレームポインタ」である。 一方gのリターンアドレスは呼び出し元関数fのプログラムカウンタ(命令ポインタとも。x86ではeip)のアドレスを格納する。
※この「C言語・C++におけるメモリ領域」の解説は、「バッファオーバーラン」の解説の一部です。
「C言語・C++におけるメモリ領域」を含む「バッファオーバーラン」の記事については、「バッファオーバーラン」の概要を参照ください。
- C言語・C におけるメモリ領域のページへのリンク