Example C to Assembly Translations
Let's look at a how a real compiler does its translations
at various optimization levels.
An Example C Program
gcd.c
/*
* gcd.c
*
* A GCD function.
*/
unsigned gcd(unsigned x, unsigned y) {
while (y > 0) {
unsigned old_x = x;
x = y;
y = old_x % y;
}
return x;
}
Translations with GCC
No Optimizations
$ gcc -S -o gcd0.s gcd.c
.file "gcd.c"
.text
.globl gcd
.type gcd, @function
gcd:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl %edi, -20(%rbp)
movl %esi, -24(%rbp)
jmp .L2
.L3:
movl -20(%rbp), %eax
movl %eax, -4(%rbp)
movl -24(%rbp), %eax
movl %eax, -20(%rbp)
movl -4(%rbp), %eax
movl $0, %edx
divl -24(%rbp)
movl %edx, -24(%rbp)
.L2:
cmpl $0, -24(%rbp)
jne .L3
movl -20(%rbp), %eax
leave
ret
.cfi_endproc
.LFE0:
.size gcd, .-gcd
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5.1) 4.4.5"
.section .note.GNU-stack,"",@progbits
Optimization Level 1
$ gcc -S -O1 -o gcd1.s gcd.c
.file "gcd.c"
.text
.globl gcd
.type gcd, @function
gcd:
.LFB0:
.cfi_startproc
movl %edi, %eax
testl %esi, %esi
je .L2
.L6:
movl $0, %edx
divl %esi
testl %edx, %edx
je .L3
movl %esi, %eax
movl %edx, %esi
jmp .L6
.L3:
movl %esi, %eax
.L2:
rep
ret
.cfi_endproc
.LFE0:
.size gcd, .-gcd
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5.1) 4.4.5"
.section .note.GNU-stack,"",@progbits
Optimization Level 3
$ gcc -S -O3 -o gcd3.s gcd.c
.file "gcd.c"
.text
.p2align 4,,15
.globl gcd
.type gcd, @function
gcd:
.LFB0:
.cfi_startproc
testl %esi, %esi
movl %edi, %eax
jne .L6
jmp .L2
.p2align 4,,10
.p2align 3
.L8:
movl %edx, %esi
.L6:
xorl %edx, %edx
divl %esi
movl %esi, %eax
testl %edx, %edx
jne .L8
.L2:
rep
ret
.cfi_endproc
.LFE0:
.size gcd, .-gcd
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5.1) 4.4.5"
.section .note.GNU-stack,"",@progbits