問題タブ [red-zone]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C プログラムのスタックとレッド ゾーンを理解する
以下は単純な C プログラムです。
Ubuntu 64 ビットで GNU デバッガーを使用して、メイン関数の最初からプログラムを段階的にデバッグしました。これがデバッガーの結果です。
ご覧のとおり、x と ptr を初期化するとき、スタック ポインターはプログラム中に変更されません。私がオンラインで見つけたのは、x と ptr が実際にはメモリのスタック セグメントのレッド ゾーンに格納されていることです。
ただし、私を混乱させる部分は次のとおりです。まず、x を宣言して 10 に設定します。x のアドレスは 0x7ffffffffdffc です。次に、ポインター ptr を x に初期化すると、ptr は x のアドレスと同じ値になります。ただし、私の目を引いたのは、ポインター自体のアドレス: 0x7fffffffe0f0 が x のアドレス (e0f0-dffc = 4) よりも 4 バイト大きいことです。これは、スタックについて学んだことと矛盾しています。上向きではなく、メモリ。
レッド ゾーンはスタックとは異なる動作をしますか?
assembly - スタック レッド ゾーンの実際のサイズは?
x86-64 System V ABIでは、の後ろのスペース$rsp - 128
は、シグナル ハンドラが触れない、いわゆるレッド ゾーンであると指定されています。私のマシンで
スタックには 2 ページしかないと予想していました。そこで、次のプログラムを作成して、どのサイズのレッド ゾーンが拡大できるかをテストしました。
したがって、プログラムは常に失敗すると予想していました。しかし、プログラムは で失敗することもあればSEGV
、正常に終了することもあります。
MAP_GROWSDOWN
動作は、次のドキュメントとまったく同じです。
このフラグはスタックに使用されます。これは、カーネル仮想メモリ システムに対して、マッピングがメモリ内で下位に拡張する必要があることを示します。戻りアドレスは、プロセスの仮想アドレス空間で実際に作成されるメモリ領域よりも 1 ページ下になります。マッピングの下にある「ガード」ページのアドレスに触れると、マッピングが 1 ページ分大きくなります。この成長は、マッピングが次に低いマッピングの上限のページ内に成長するまで繰り返すことができ、その時点で「ガード」ページに触れると
SIGSEGV
信号が発生します。
この質問で説明したように、作成されたマッピングはそのようには成長MAP_GROWSDOWN
しPROT_GROWSDOWN
ません。
質問:上記の理由を組み合わせると、使用する唯一のマッピングがMAP_GROWSDOWN
メイン スレッドの[stack]
マッピングであるというのは本当ですか?
assembly - x86_64 でスタック ポインターの代わりにフレーム ポインターを使用する
GCC を使用して単純な C コードをアセンブリにコンパイルすると、次の出力が得られます。
私の質問は、frame base pointer (rbp)
を操作する代わりに へのオフセットを使用する理由stack pointer (rsp)
です。それがスタックポインタを持つことの要点ではありませんか?
rsp
このプロセスのスタックが、値を書き込むときにデクリメントされないため、スタックが使用されていることさえ知らない他のプロセス (例としてガベージ コレクション) によって上書きされた場合はどうなるでしょうか。
c - C 配列の逆アセンブルで奇妙な結果が生じる
上記のコードは生成します
コードを少し変更すると
生成されたアセンブリは
なぜ以前の作品に割り当てられないのか理解できないので、これはまだ奇妙です. 私は -O0 で実行しているので、gcc は最適化しません。gcc が間違ったサイズの配列のコードを作成するのはなぜですか?
同様に x86 の場合
-m32 でコンパイルすると、次のようになります。
この余分な 12 バイトはどこから来たのですか? また、-m32 には char test[50] のサブ命令があるのに、x86_64 にはないのはなぜですか?