-mpreferred-stack-boundary
GNUコンパイラでのコンパイル中のオプションの使用法を知りたいです。ドキュメントを確認しましたが、説明がわかりません。誰か説明してくれませんか。
3 に答える
GNU デバッガーでのコンパイル中に -mpreferred-stack-boundary オプションを使用する方法を知りたいです。
このオプションは、デバッガーとはまったく関係ありません。
バイナリで生成されたコードに影響します。デフォルトでは、GCC はすべての関数が開始直後にスタック ポインターを 16 バイト境界に揃えるように調整します (これは、ローカル変数があり、sse2
命令を有効にする場合に重要になる場合があります)。
デフォルトを eg に変更する-mpreferred-stack-boundary=2
と、GCC はスタック ポインターを 4 バイト境界に揃えます。これにより、ルーチンのスタック要件が軽減されますが、コード (または呼び出すコード)がを使用するとクラッシュするsse2
ため、通常は安全ではありません。
プログラムがメモリに配置されるときに使用するバイト境界に関係しています。
スタック境界 = 2 が行うことは、スタックが dword サイズのインクリメントに設定されることを保証することです。これにより、マシンがスタックを最適化できなくなります。
チェックアウトする場合:
`info gcc and search by entering "/mpreferred-stack-boundary"` it says:
>-mpreferred-stack-boundary=num
>
スタック境界を、2 を num バイト境界まで上げたものに合わせて維持しようとします。-mpreferred-stack-boundary が指定されていない場合、デフォルトは 4 (16 バイトまたは 128 ビット) です。
デフォルトのスタック境界の 4 は、Intel 386 と AMD x86-64 マシンの両方で同じです。
64 ビット Linux マシンで「m-preferred-stack-boundary=2」オプションを使用しようとすると、コンパイルがエラーで失敗する
「-mpreffered-stack-boundary=2 は 4 から 12 の間ではありません」。
これは、アドレス フィールドの幅が 64 ビット マシンで 4 バイトから 8 バイトに増加したためです。したがって、2^2=4 バイトであるため、stack-boundary=2 で個々のチャンクを書き込むことはできません。ただし、興味深いことに、スタック境界が 3 の場合でも、32 ビット マシンと 64 ビット マシンの両方でエラーが返されます。これは 8 バイト境界になります。
私は 10 の評判を持っていないので、リンクを含めることはできません...しかし、検索するとかなり簡単に情報が表示されます.8 バイトはスタックの位置合わせがずれやすいため、これはセキュリティ機能であると言えます...間違いありません他の誰かがよく知っているか、詳細を知っています。
スタックがどのようにずれたか 言う:
スタック上でこの値が適切に配置されるようにするには、スタック境界を、スタックに格納されている値が必要とするのと同じように配置する必要があります。さらに、すべての関数は、スタックの整列を維持するように生成する必要があります。したがって、優先度の高いスタック境界でコンパイルされた関数を、優先度の低いスタック境界でコンパイルされた関数から呼び出すと、スタックの位置合わせがずれてしまう可能性が高くなります。コールバックを使用するライブラリでは、常に既定の設定を使用することをお勧めします。
この余分なアラインメントは余分なスタック スペースを消費し、一般的にコード サイズを増加させます。組み込みシステムやオペレーティング システム カーネルなど、スタック スペースの使用に敏感なコードでは、優先アラインメントを -mpreferred-stack-boundary=2 に減らしたい場合があります。