7

次の疑問があります。

私たちが知っているように、System V x86-64 ABI は、スタック フレーム内に約固定サイズ (128 バイト) の領域、いわゆるレッドゾーンを提供します。したがって、結果として、たとえば を使用する必要はありませんsub rsp, 12。作るだけmov [rsp-12], X、それだけです。

しかし、私はその考えを理解することはできません。なぜそれが重要なのですか?sub rsp, 12レッドゾーンなしにする必要はありますか?結局のところ、最初はスタック サイズが限られているのに、なぜsub rsp, 12重要なのでしょうか? スタックの一番上を追跡できることはわかっていますが、その時点では無視しましょう。

rsp一部の命令が値 ( など)を使用することは知っていretますが、その瞬間は気にしません。

問題の核心は次のとおりです。レッドゾーンはありません。

function:
    mov [rsp-16], rcx
    mov [rsp-32], rcx
    mov [rsp-128], rcx
    mov [rsp-1024], rcx
    ret

との違いは?

function:
    sub rsp, 1024
    mov [rsp-16], rcx
    mov [rsp-32], rcx
    mov [rsp-128], rcx
    mov [rsp-1024], rcx
    add rsp, 1024
    ret
4

2 に答える 2

3

あなたの例ではオフセットが間違っているため、意味がありません。コードは、スタック ポインターの下の領域にアクセスしないでください。これは未定義です。レッド ゾーンは、スタック ポインターの下の最初の 128 バイトを保護するためにあります。2 番目の例は次のようになります。

function:
    sub rsp, 1024
    mov [rsp+16], rcx
    mov [rsp+32], rcx
    mov [rsp+128], rcx
    mov [rsp+1016], rcx
    add rsp, 1024
    ret

関数が必要とするスクラッチ スペースの量が最大 128 バイトの場合、スタックを調整する必要なく、スタック ポインターの下のアドレスを使用できます。これが最適化です。比較:

function:        // Not using red-zone.
    sub rsp, 128
    mov [rsp+120], rcx
    add rsp, 128
    ret

レッドゾーンを使用した同じコード:

function:        // Using the red-zone, no adjustment of stack
    mov [rsp-8], rcx
    ret

スタック ポインターからのオフセットに関する混乱は通常、コンパイラがスタック (RSP) からの正のオフセットではなく、フレーム (RBP) から負のオフセットを生成するために発生します。

于 2016-06-21T11:21:38.180 に答える