bugfix> c > 投稿

プログラムの場合、ローカル変数はスタックで定義および割り当てられますが、ローカル変数を定義する順序はそれを使用する順序と同じではないのではないかと思います。 たとえば、メイン関数では、前述のように、int a b cが定義されています。これは、a b cがスタックに割り当てられていることを意味します。つまり、変数aがスタックの一番下にある場合、変数が最初に使用されると、スタックからどのようにポップアウトされますか? または、ebpはすべての変数が保存されている場所を指しますか?

回答 1 件
  • 基本的に関数内で、ローカル変数はスタックフレームに保存されます。スタックフレーム内では、変数のアクセス順序はランダムにすることができます。これを読むことをお勧めします:http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch10s07.html

    次のコードを検討してください

    int main (void)
    {
      int a = 1, b = 2, c = 3;
      c = c + 55;
      a = a + 10;
      return 0;
    }
    
    

    コンパイラは次のコードを生成できます

    main:
    .LFB0:
            .cfi_startproc
            push    rbp
            .cfi_def_cfa_offset 16
            .cfi_offset 6, -16
            mov     rbp, rsp
            .cfi_def_cfa_register 6
            mov     DWORD PTR [rbp-4], 1
            mov     DWORD PTR [rbp-8], 2
            mov     DWORD PTR [rbp-12], 3
            add     DWORD PTR [rbp-12], 55
            add     DWORD PTR [rbp-4], 10
            mov     eax, 0
            pop     rbp
            .cfi_def_cfa 7, 8
            ret
            .cfi_endproc
    
    

    変数 a  、 b  および c  場所 rbp-4 に保存されます 、 rbp-8  および rbp-12 、したがって、各変数は4バイトを取得します(私のシステムでは)。スタックは下向きに成長し、この関数のスタックフレームの開始は rbp の内容によって示されるため、マイナスです。 。

    次に、最初の c = c + 55  そして、 a = a + 10  プッシュまたはポップ操作を行わず、 add DWORD PTR [rbp-12], 55 を使用してロケーションに直接アクセスするだけです  および add DWORD PTR [rbp-4], 10  それぞれ。コンパイラは、これらの変数がスタックフレーム内のどこにあるかを認識します。

    push rbp に注意してください  変数が宣言およびアクセスされる前。この操作は rbp の現在の値を保存しました  (ベースポインター、64ビット)、スタックフレーム上。次の rbp  この関数の制限を示す新しい値を取得するために更新されます。この制限内であれば、すべてのローカル変数を保存できます。 pop rbp にも注意してください  戻る前に。これにより、 rbp の古い値が復元されます  前に保存されたスタックフレームから、 ret の後 、古い状態に戻ることができます。

あなたの答え