コードの最適化
関数
#include <stdio.h> void func1 (int x, int a[]) { int i, j; for (i = 0; i < 10; i ++) { a[i] = i; } } int main (void) { int x[10]; func1 (5, x); return 0; }
gcc -O0 -S でこんぱいる
.file "ex4.c" .text .globl func1 .type func1, @function func1: pushl %ebp movl %esp, %ebp subl $16, %esp movl $0, -4(%ebp) jmp .L2 .L3: movl -4(%ebp), %eax sall $2, %eax addl 12(%ebp), %eax movl -4(%ebp), %edx movl %edx, (%eax) addl $1, -4(%ebp) .L2: cmpl $9, -4(%ebp) jle .L3 leave ret .size func1, .-func1 .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $56, %esp leal -40(%ebp), %eax movl %eax, 4(%esp) movl $5, (%esp) call func1 movl $0, %eax leave ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
gcc -O1 -Sでこんぱいる
.file "ex4.c" .text .globl func1 .type func1, @function func1: pushl %ebp movl %esp, %ebp movl 12(%ebp), %edx movl $0, %eax .L2: movl %eax, (%edx,%eax,4) addl $1, %eax cmpl $10, %eax jne .L2 popl %ebp ret .size func1, .-func1 .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $56, %esp leal -40(%ebp), %eax movl %eax, 4(%esp) movl $5, (%esp) call func1 movl $0, %eax leave ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
mainは変わらず。
func1のfor文で変わってる。
俺がわかる範囲だと、
配列のインデックスに使ってるeaxの計算を、
sall云々からmovlで一行にしてる。
movl %eax, (%edx,%eax,4)
右の(%edx,%eax,4)は、(edx+eax*4)みたいな計算をする。
あとは、ジャンプの回数を少なくしたり。
gcc -O2 -Sでこんぱいる
.file "ex4.c" .text .p2align 4,,15 .globl func1 .type func1, @function func1: pushl %ebp xorl %eax, %eax movl %esp, %ebp movl 12(%ebp), %edx .p2align 4,,7 .p2align 3 .L2: movl %eax, (%edx,%eax,4) addl $1, %eax cmpl $10, %eax jne .L2 popl %ebp ret .size func1, .-func1 .p2align 4,,15 .globl main .type main, @function main: pushl %ebp xorl %eax, %eax movl %esp, %ebp subl $48, %esp leal -40(%ebp), %edx .p2align 4,,7 .p2align 3 .L7: movl %eax, (%edx,%eax,4) addl $1, %eax cmpl $10, %eax jne .L7 xorb %al, %al leave ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
もはやfunc1は呼んでいない。
そのかわり同様の構造がmainに組み込まれている。
それと頻繁にalign命令を使ってロケーションカウンタを調整してる。
他はeaxを0にするために、xorで0にしてる。
alを使ってるのは、レジスタの操作を最小限にしようとしているからだと思う。
gcc -O3 -s でこんぱいる
.file "ex4.c" .text .p2align 4,,15 .globl func1 .type func1, @function func1: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax movl $0, (%eax) movl $1, 4(%eax) movl $2, 8(%eax) movl $3, 12(%eax) movl $4, 16(%eax) movl $5, 20(%eax) movl $6, 24(%eax) movl $7, 28(%eax) movl $8, 32(%eax) movl $9, 36(%eax) popl %ebp ret .size func1, .-func1 .p2align 4,,15 .globl main .type main, @function main: pushl %ebp xorl %eax, %eax movl %esp, %ebp popl %ebp ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
配列の中は0〜9が確定しているので、その値がぶち込まれてしまった。