1. 前世今生
a.out ---- assembler output 汇编程序输出(其实该叫链接器输出)
早起程序创建时还没有连接器,汇编后时直接保存到a.out里的,就算后来有了链接器,也就沿用了这个叫法
2. 怎么出生滴
首先写个小程序 t1.c
#include <stdio.h>#define WORD "Hello World"#ifdef TEST
#define PRE_WORD "We Say"
#else
#define PRE_WORD "I Say"
#endifint main(void){//Do who need say Hello Worldprintf("%s: %s\n", PRE_WORD, WORD);return 0;
}
2.1 其次用这个命令预处理一下
gcc -E t1.c -o t1.i //只进行预编译
可以看出,预处理做了哪些事情
----处理#include指令,将被包含的头文件插入
----删除#define宏,并将定义展开
----处理条件编译
----删除注释
这几个都是比较明显的处理,还有一些其他的处理,留作思考题吧
2.2 再用这个命令编译
gcc -S t1.c -o t1.s //编译
.file "t1.c".text.section .rodata
.LC0:.string "Hello World"
.LC1:.string "I Say"
.LC2:.string "%s: %s\n".text.globl main.type main, @function
main:
.LFB0:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6leaq .LC0(%rip), %rdxleaq .LC1(%rip), %rsileaq .LC2(%rip), %rdimovl $0, %eaxcall printf@PLTmovl $0, %eaxpopq %rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size main, .-main.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0".section .note.GNU-stack,"",@progbits
此时,已经将代码由文本语言转换成机器语言了,主要做了这些事
----词法分析
----语法分析
----语义分析
----目标文件的优化和生成
2.3 继续用命令处理
gcc -c t1.i -o t1.o
此时汇编过程已经结束,生成了目标文件.o,但此时还不能正常运行.o文件,加了权限也不行
objdump -t t1.o //查看生成的符号表
t1.o: file format elf64-x86-64SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 t1.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .rodata 0000000000000000 .rodata
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000002a main
0000000000000000 *UND* 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000 *UND* 0000000000000000 printf
2.4 最后还得转换成二进制才能执行
gcc t1.o -o a.out
当然,这个a.out是手动写的,但实际情况中是系统自动生成滴