各个编译命令的含义
gcc -E test.c -o test.i
编译预处理,生成.i文件
gcc -S test.i -o test.s
汇编生成.s文件,其中可以使用-O -O2 -O3编译优化选项(稍后讨论)
gcc -c test.s -o test.o
汇编生成目标文件(.o)
gcc test.o -o test.exe
链接生成可执行文件
不同编译选项的作用
编译预处理
在我短短的一个排序程序前添加了八百多行的代码,其中包括typedef的类型定义、extern声明外部函数、include语句声明所需的头文件等。
编译优化
- 不使用编译优化
在不使用编译优化的情况下,一个二重循环需要用十几个LOOP实现
.file "test.c"
.section .rodata
.LC0:
.string "%d "
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $64, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
;寄存器存放数组
movl $3, -48(%rbp)
movl $6, -44(%rbp)
movl $14, -40(%rbp)
movl $25, -36(%rbp)
movl $7, -32(%rbp)
movl $18, -28(%rbp)
movl $96, -24(%rbp)
movl $1, -20(%rbp)
movl $35, -16(%rbp)
movl $10, -12(%rbp)
movl $0, -60(%rbp)
jmp .L2
.L3:
movl -60(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
addl $1, -60(%rbp)
.L2:
;第一层循环
cmpl $9, -60(%rbp)
;偏序关系不符,需要调换顺序
jle .L3
movl $10, %edi
call putchar
movl $0, -60(%rbp)
;继续下一次迭代
jmp .L4
.L8:
movl -60(%rbp), %eax
addl $1, %eax
movl %eax, -56(%rbp)
jmp .L5
.L7:
movl -56(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %edx
movl -60(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %eax
cmpl %eax, %edx
jge .L6
movl -60(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %eax
movl %eax, -52(%rbp)
movl -56(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %edx
movl -60(%rbp), %eax
cltq
movl %edx, -48(%rbp,%rax,4)
movl -56(%rbp), %eax
cltq
movl -52(%rbp), %edx
movl %edx, -48(%rbp,%rax,4)
.L6:
addl $1, -56(%rbp)
.L5:
cmpl $9, -56(%rbp)
jle .L7
addl $1, -60(%rbp)
.L4:
;将a[j+1]放入$9中
cmpl $9, -60(%rbp)
jle .L8
movl $0, -60(%rbp)
jmp .L9
.L10:
movl -60(%rbp), %eax
cltq
movl -48(%rbp,%rax,4), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
addl $1, -60(%rbp)
.L9:
cmpl $9, -60(%rbp)
jle .L10
movl $10, %edi
call putchar
movl $0, %eax
movq -8(%rbp), %rcx
xorq %fs:40, %rcx
je .L12
call __stack_chk_fail
.L12:
;排序完成
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
- 使用 -O3 优化(开启全部优化选项)
我原以为会进行很多循环上的优化,实则整个循环结构上没有做太大的改动,而是在一些细节的语句上进行优化,从而缩短程序执行时间,如栈操作、判断语句的位置、分支跳转的优化等等。