64

この質問は、スタック オーバーフローの質問への回答から来ています。「コンパイラはメモリ内の変数にスペースを割り当てる」と本に書かれているのはなぜですか? 、ここで、スタックに変数を割り当てるとどうなるか、およびコンパイラが割り当てるメモリのサイズを知っているコードをどのように生成するかをOPに示しようとしました。どうやら、コンパイラは必要以上のスペースを割り当てているようです。

ただし、以下をコンパイルすると

#include <iostream>
using namespace std;

int main()
{
    int foo;
    return 0;
}

Visual C++ 2012 を最適化なしでデバッグ モードでコンパイルすると、次のアセンブラー出力が得られます。

int main()
{
00A31CC0  push        ebp
00A31CC1  mov         ebp,esp
00A31CC3  sub         esp,0CCh  // Allocates 204 bytes here.
00A31CC9  push        ebx
00A31CCA  push        esi
00A31CCB  push        edi
00A31CCC  lea         edi,[ebp-0CCh]
00A31CD2  mov         ecx,33h
00A31CD7  mov         eax,0CCCCCCCCh
00A31CDC  rep stos    dword ptr es:[edi]
   int foo;
   return 0;
00A31CDE  xor         eax,eax
}

私のプログラムにもう1つ追加するintと、上記のコメント行が次のようになります。

00B81CC3  sub         esp,0D8h // Allocate 216 bytes

上にリンクされた私の回答で@JamesKanzeによって提起された質問は、コンパイラがなぜVisual C ++(別のコンパイラで実験を行っていない)だけでなく、それぞれ204バイトと216バイトを割り当てたのかということです。必要なのは4つだけで、2番目には8つしか必要ありませんか?

このプログラムは、32 ビットの実行可能ファイルを作成します。

技術的な観点から、4 バイトではなく 204 バイトを割り当てる必要があるのはなぜですか?

編集:

2 つの関数を呼び出して、main にadoubleと twoを作成すると、次のようになります。int

 01374493  sub         esp,0E8h  // 232 bytes

上記の編集と同じプログラムの場合、リリース モード (最適化なし) でこれを行います。

 sub    esp, 8                // Two ints
 movsd  QWORD PTR [esp], xmm0 // I suspect this is where my `double` goes
4

1 に答える 1