博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学习笔记之编译和链接
阅读量:6831 次
发布时间:2019-06-26

本文共 1262 字,大约阅读时间需要 4 分钟。

#include <stdio.h>

int main(int argc,char **argv)
{
       printf("hello world\n");
       return 0;
}
在linux下,使用GCC来编译helloworld 程序时,只需使用最简单的命令:
& gcc hello.cpp -o a
或$ gcc hello.cpp;  $./a.out
即可在屏幕上输出hello world
事实上,上述过程可以分解为4个步骤,分别是预处理(Prepressing)、编译(Compilation)、汇编(Assembly)和链接(Linking),如下图所示:
 1、预编译
首先是源代码文件hello.c和相关的头文件,如stdio.h等被预编译器cpp预编译成一个.i文件。对于C++程序来说,它的源代码文件的扩展名可能是.cpp或.cxx,头文件的扩展名可能是.hpp,而预编译后的文件扩展名是.ii。第一步预编译后的文件扩展名是.ii。第一步预编译的过程相当于如下命令(-E表示只进行预编译):
$ gcc -E hello.c -o hello.i
或者:$ cpp hello.c > hello.i
预编译过程主要处理那些原文件中以“#”开始的预编译指令。比如"#include"、"#define"等,主要处理规则如下:
>将所有的"#define"删除,并展开所有的宏定义。
>处理所有条件预编译指令,比如"#if"、"#ifdef"、"#elif"、"#else"、"#endif"。
>处理"#include"预编译指令,将被包含的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能包含其它的文件。
>删除所有的注释"//"和"/**/"。
>添加行号和文件名标识,比如#2 "hello.c" 2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号。
>保留所有#pragma 编译器指令,因为编译器需要使用。
2、编译
编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件,这个过程是整个程序构建的核心部分。上例的编译部分相当于:
$ gcc -S hello.i -o hello.s
 3、汇编
汇编器是将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。所以汇编器的汇编过程相对于编译器比较简单,他没有复杂的语法,也没有语义,也不需要做指令优化,只是根据汇编指令和机器指令的对照表一一翻译就可以了。上例的汇编过程可以用汇编器as来完成:
$ as hello.s -o hello.o
或者:
$ gcc -c hello.s -o hello.o
或者使用gcc命令从C源代码文件开始,经过预编译、编译和汇编直接输出目标文件(Object File):
$ gcc -c hello.c -o hello.o
4、链接
先总结至此,后续补充.......

转载地址:http://edtkl.baihongyu.com/

你可能感兴趣的文章
getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
查看>>
退出Activity(转)
查看>>
前端开发者喜欢的20个学习文档和指南
查看>>
“超级课程表”余佳文:初生牛犊不怕虎
查看>>
php 不依赖数据实现删除图片,核心代码
查看>>
[翻译]:SQL死锁-锁的类型
查看>>
web.xml 详细介绍
查看>>
[转]Why Not Paxos
查看>>
C# 反射 通过类名创建类实例
查看>>
VC中获取窗体句柄的各种方法
查看>>
jsp各部分编码的含义
查看>>
知方可补不足~Sqlserver中的几把锁和.net中的事务级别 回到目录
查看>>
【高德地图API】那些年我们一起开发的APP—即LBS应用模式分享
查看>>
通过广播来监听屏幕点亮和关闭状态
查看>>
Cocos2dx引擎10-事件派发
查看>>
基于jQuery的宽屏可左右切换的焦点图插件
查看>>
IT技术需求建立时需考虑的因素
查看>>
猛醒:也许我们一生追求的都错了!
查看>>
IDDD 实现领域驱动设计-理解领域和子域
查看>>
GitHub基本操作
查看>>