3

cのアセンブリがどのように生成されるかを理解しようとしています。サンプルプログラムを書いて逆アセンブルしました。

int main()
{
int a = 100;
}

生成されたアセンブリ:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $48, %rsp    #,
call    __main   #
movl    $100, -4(%rbp)   #, a
leave
ret

それは私にとって非常に簡単です。しかし、アセンブリにポインターを含めると、アセンブリがわかりません。

C プログラム:

int main()
{
int a = 100;
int *p = &a;
}

生成されたアセンブリ:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $48, %rsp    #,
call    __main   #
movl    $100, -12(%rbp)  #, a
leaq    -12(%rbp), %rax  #, tmp59
movq    %rax, -8(%rbp)   # tmp59, p
leave
ret

ローカル変数 a が、ポインターを持たない以前のスニップと比較して、スタック内の別のオフセットにプッシュされる理由がわかりません。

質問 #2: 4 つのローカル変数がある場合、スタック フレームは subq $48、%rsp ですが、ローカル変数の 1 つをポインターに変換すると、subq $64 になります。どうしてですか。

C コード:

int main()
{
int a = 100;
int *p = &a;
int b = 10;
int c = 20;
}

組み立て:

pushq   %rbp     #
movq    %rsp, %rbp   #,
subq    $64, %rsp    #,
call    __main   #
movl    $100, -20(%rbp)  #, a
leaq    -20(%rbp), %rax  #, tmp59
movq    %rax, -8(%rbp)   # tmp59, p
movl    $10, -12(%rbp)   #, b
movl    $20, -16(%rbp)   #, c
leave
ret

また、ローカル変数のないメイン関数のスタック フレームが 2 * 16 バイト (32 バイト) にアラインされている理由を説明できると助かります。簿記の練習のためだと思いますが、正確な理由は何ですか?

ありがとう、

4

2 に答える 2

0

コンパイラは、単純にコードを 1 行ずつ c からアセンブリに変換するわけではありません。最適化コンパイラは、実行されないコードの削除、ループ パフォーマンスの最適化、スタック/メモリ使用量の最適化などを試みるコードに対して一連の分析を行います。コンパイラは、メモリを割り当てる場所と変数を格納する場所を決定するまでに、a と p の両方を認識し、最適と思われる場所に配置します。

于 2013-04-28T18:41:01.510 に答える