2016-06-12 4 views
1

このコードはgcc 5.3.1でコンパイルされました。Cおよびアセンブリのローカル変数と静的変数の追加方法

組立説明書には、GNU/Linuxのはx86_64のプロセッサ上で実行されているdisassemble main

オペレーティングシステムを使用して、GDB 7.11経由で生成されました。最初の例で


int main() { 
    int i = 0; 
    return ++i; 
} 

push %rbp 
mov %rsp,%rbp 
movl $0x0,-0x4(%rbp) 
addl $0x1,-0x4(%rbp) 
mov -0x4(%rbp),%eax 
pop %rbp 
retq 

int main() { 
    static int i; 
    return ++i; 
} 

push %rbp 
mov %rsp,%rbp 
mov 0x200b54(%rip),%eax 
add $0x1,%eax 
mov %eax,0x200b4b(%rip) 
mov 0x200b45(%rip),%eax 
pop %rbp 
retq 

後者の場合、値は最初eaxレジスタに転送されなければならないのに対し、メモリアドレスは、直接的に操作されています。誰かが何が起こっているのか説明できますか?

+1

静的変数は、ローカル変数と同じ方法で処理されません。それらはプロセスメモリの特定の部分に格納する必要があります。コンパイラはそれらを最適化することはできません。少なくとも、余分な負荷をかけてはいけません。 – Bakuriu

+0

ああ。何らかの理由で私はALUを含むすべての操作がレジスタを介して行われなければならないと考えました。 @Bakuriu –

+1

静的記憶域クラスは、スコープの外に出たり出たりするたびに、プログラムの生存期間中にローカル変数を作成および破棄するのではなく、コンパイラに指示します。 – mssirvi

答えて

1

何が起こっているかは、gccにアセンブリを最適化するよう指示していないということです。したがって、どのアセンブリが発行するのかは、CPUが何を行うことができるのかを実際に表すものではありません。最適化されたアセンブリでは、2つの配列は、おそらく次のようになります。

# adding 1 an automatic variable in register eax 
add $1,%eax 

# alternatively 
inc %eax 

# adding 1 to an automatic variable on the stack 
add $1,12(%rbp) 

# alternatively 
inc 12(%rbp) 

# adding 1 to a static variable 
add $1,i(%rip) 

# alternatively 
inc i(%rip) 

ripは、命令ポインタです。 amd64では、静的変数へのアクセスは、通常、PICコードを有効にするために命令ポインタに対して行われます。

関連する問題