“Hello World”背后的那些事

转载请标注  http://blog.csdn.net/zgh1988/article/details/7863888

#include <stdio.h>
int main()
{
    printf("Hello World");
    return 0;
}

这是一个“Hello World”程序,相信大家对它再熟悉不过了。现在就让我们来探讨该程序是如何输出“Hello World”,在控制台输出“Hello World”的背后,是谁在为它付出?

1、如何产生一个可运行程序

在Linux环境下,我们可以使用GCC编译Hello World程序,只需要

gcc hello.c

./a.out


上述过程可以分解为4个步骤来完成,分别是预处理(pre-processing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。如下图所示:


 

(1)预处理

C语言的预处理主要由三方面的内容:

1 宏定义; #define PI 3.1415

2 文件包含; #include<stdio.h>  #include "hello.h"

3 条件编译; #if  #ifdef #elif  #else #endif

4 删除所有的注释

Linux环境下的预处理命令:

gcc -E hello.c -o hello.i

(2)编译

编译过程就是把预处理完的文件进行一系列的 词法分析, 语法分析,  语义分析, 中间代码的生成及优化, 目标代码的生成与优化。

Linux环境下的编译命令:

gcc -S hello.i -o hello.s

(3)汇编

汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应着一条机器指令。

linux环境下的汇编命令:

as hello.s -o hello.o

gcc -c hello.s -o hello.o

(4)链接

随着程序的复杂性越来越高,我们不得不将程序分成不同的模块来进行独立的编译。而链接器的主要任务就是使各个模块之间能够正确的衔接在一起,形成可运行程序。链接过程主要包括了 地址和空间分配,符号解析,重定位等步骤。

 

2、编译过程是怎样?

如下图所示:



下面我们将以 y = ( x + 4 ) * ( 2 + 6 )来分析这个过程 

(1)词法分析

词法分析阶段,就是利用扫描器(Scanner)对源程序进行遍历,识别出源程序中的各个记号(token)。源程序中常见的记号可以分为以下几大类:

1 关键字;    保留字

2 标识符;    变量名,函数名 x, y,z

3 字面量;    常数和字符串常量 60 、“zgh”

4 特殊符号;  + - * / ;

 

y = ( x + 4 ) * (2 + 6 )


(2)语法分析

对词法分析产生的记号进行语法分析,从而产生语法树(Syntax tree)。

y = ( x + 4 ) * (2 + 6 )



(3)语义分析

语义分析器根据语义规则对语法树中的语法单元进行静态语义检查,如类型检查和转换。比如讲一个浮点型赋值给一个指针的时候,语义分析程序会发现这个类型不匹配,编译器将会报错。在语义分析阶段,编译器所能分析的语义是静态语义。

y = ( x + 4 ) * (2 + 6 )


 

(4)中间代码的生成

源代码优化器往往会将整个语法树转换成中间代码(Intermediate Code)。

常见的中间代码有:三地址码。

例如:

t1 = 2 + 6;

t2 = x + 4;

t3 = t2 * t1;

y = t3;

优化之后:

t2 = x + 4

t2 = t2 * 8

y = t2

(5)目标代码生成与优化



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值