アプリケーションレベル(Linuxアプリケーションプロセスなど)では、仮想アドレスのみが存在します。ローカル変数はスタック上(またはレジスター内)にあります。スタックは呼び出しフレームで編成されます。コンパイラは、現在の呼び出しフレーム内のローカル変数のオフセット、通常はスタックポインタまたはフレームポインタレジスタを基準にしたオフセットを生成します(したがって、ローカル変数のアドレスは、たとえば再帰関数では、実行時にのみ認識されます)。
詳細を理解するために、デバッガーで再帰関数を段階的に実行し、gdb
ローカル変数のアドレスを表示してみてください。bt
のコマンドも試してくださいgdb
。
タイプ
cat /proc/self/maps
そのコマンドを実行するプロセスのアドレス空間(および仮想メモリマッピング)を理解するため。cat
カーネル内では、仮想アドレスから物理RAMへのマッピングは、ページングを実装してMMUを駆動するコードによって行われます。一部のシステムコール(特にmmap(2)など)は、プロセスのアドレス空間を変更する可能性があります。
Some early computers (e.g. those from the 1950-s or early 1960-s like CAB 500 or IBM 1130 or IBM 1620) did not have any MMU, even the original Intel 8086 didn't have any memory protection. At that time (1960-s), C did not exist. On processors without MMU you don't have virtual addresses (only physical ones, including in your embedded C code for a washing-machine manufacturer). Some machines could protect writing into some memory banks thru physical switches. Today, some low end cheap processors (those in washing machines) don't have any MMU. Most cheap microcontrollers don't have any MMU. Often (but not always), the program is in some ROM so cannot be overwritten by buggy code.