您的位置:首页 > 职场人生

程序员的自我修养: 编译器工作过程

2010-03-04 23:17 281 查看
//hello.c
#include <stdio.h>
int main()
{
printf("Hello world/n");
return 0;
}


hello.c的编译过程如下:

Source Code(hello.c)

Header Files(Stdio.h)                         - 预处理(Prepressing)   ->  hello.i   - 编译(Compilation) ->  hello.s -汇编(Assembly) (汇编器是将汇编代码转变成机器可执行的机器指令)

->  hello.o
->  链接(Linking) -> a.out
Static Library


hello.i的部分内容如下:

# 1 "/usr/include/bits/sys_errlist.h" 1 3 4
# 27 "/usr/include/bits/sys_errlist.h" 3 4
extern int sys_nerr;
extern __const char *__const sys_errlist[];
# 827 "/usr/include/stdio.h" 2 3 4

extern int fileno (FILE *__stream) __attribute__ ((__nothrow__)) ;

extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__)) ;
# 846 "/usr/include/stdio.h" 3 4
extern FILE *popen (__const char *__command, __const char *__modes) ;

extern int pclose (FILE *__stream);

extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 886 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 916 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
int main()
{
int i = 0;
i = (2>3?2:3);
printf("Hello world/n");
return 0;
}


hello.s的内容如下:

.file	"hello.c"
.section	.rodata
.LC0:
.string	"Hello world"
.text
.globl main
.type	main, @function
main:
pushl	%ebp
movl	%esp, %ebp
andl	$-16, %esp
subl	$32, %esp
movl	$0, 28(%esp)
movl	$3, 28(%esp)
movl	$.LC0, (%esp)
call	puts
movl	$0, %eax
leave
ret
.size	main, .-main
.ident	"GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section	.note.GNU-stack,"",@progbits


总的来说, 过程如下:

预编译(生成hello.i),编译(生成hello.s),汇编(生成hello.o),链接(生成a.out)

1. 编译的过程又有如下过程:

源代码
-  词法分析(Scanner)->Tokens
-  语法分析(Paraser)    -> Syntax Tree
- 语义分析器(Semantic Analyzer)  -> Commented Syntax Tree
-  源代码级优化器(Source Code Optimizer)->Intermediate Representation
-  代码生成器(Code Generator)->Target Code
-  目标代码优化器(Code Optimizer)->Final Target Code


2. 链接的过程如下:

Library
Object File a.o     -Link->a.out
Object File b.o


链接时,假如我们在程序模块main.c中使用另一个模块服从func.c中的函数foo(), 在编译时, main.c假设foo的地址是0,当连接时,main.c才在func.c中查找foo()的地址。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: