初めに
C言語をアセンブリ言語へコンパイルして最適化する場合としない場合の違いを確認します。
C言語ソース
int sum() {
int total = 0;
for (int i = 1; i <= 100; i++) {
total += i;
}
return total;
}
最適化の設定
最適化無し (-O0)
gcc -S -O0 -masm=intel sum.c -o sumO0.s
最大最適化 (-O3)
gcc -S -O3 -masm=intel sum.c -o sumO3.s
最適化の有無による差異
最適化しない場合
sumO0.s
.file "sum.c"
.intel_syntax noprefix
.text
.globl _sum
.def _sum; .scl 2; .type 32; .endef
_sum:
LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
sub esp, 16
mov DWORD PTR [ebp-4], 0
mov DWORD PTR [ebp-8], 1
jmp L2
L3:
mov eax, DWORD PTR [ebp-8]
add DWORD PTR [ebp-4], eax
add DWORD PTR [ebp-8], 1
L2:
cmp DWORD PTR [ebp-8], 100
jle L3
mov eax, DWORD PTR [ebp-4]
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
最適化する場合
sumO3.s
.file "sum.c"
.intel_syntax noprefix
.text
.p2align 4,,15
.globl _sum
.def _sum; .scl 2; .type 32; .endef
_sum:
LFB0:
.cfi_startproc
mov eax, 5050
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
分析
最適化しない場合は、C言語の書き方通りに100回繰り返して計算しているが、この書き方だとtotalは毎回5050となる。最適化した場合は直接5050を代入している。
mov DWORD PTR [ebp-4], 0
mov DWORD PTR [ebp-8], 1
jmp L2
L3:
mov eax, DWORD PTR [ebp-8]
add DWORD PTR [ebp-4], eax
add DWORD PTR [ebp-8], 1
L2:
cmp DWORD PTR [ebp-8], 100
jle L3
この10行が1行に短縮された。
mov eax, 5050
動作環境
windows7 Version6.1.7601
GCC-6.3.0-1
(帰省中につき一時的に昔のパソコンを使用している。windows7が懐かしい。。。)