程序员的自我修养笔记之一--被隐藏的过程

一个程序的正确执行需要经过4个阶段,分别是预处理(Preprecessing)、编译(Compilation)、汇编(Assenmbly)和链接(Linking)。

1、预编译

预编译过程主要处理那些源代码文件中的以“#”开始的预编译指令。比如,“#include” “#define”等,主要处理规则如下:

①将所有的“#define”删除,并且展开所有的宏定义;

②处理所有条件预编译指令,比如"#if" "#ifdef" "#elif" "#else"  "#endif"。

③处理“#include”预编译指令,将被包括的文件插入到该预编译指令的位置。注意,这个过程是递归进行的,也就是说被包含的文件可能还包括其他文件。

④删除所有的注释“//” “/**/”

⑤添加行号和文件标识,比如#2 “hello.c” 2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或者警告时能够显示行号;

⑥保留所有#pragma编译指令吗因为编译器要使用它们。

经过预编译后的.i文件不包含任何宏定义,应为所有的宏已经被展开,并且包含的头文件也已经被插入到.i中去。

2、编译

编译的过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件,这个过程往往是我们所说的整个程序构建的核心部分,也是最复杂的部分之一。

现在gcc版本把预编译和编译连个步骤合并成一个步骤,使用一个叫ccl的程序来完成这个步骤。

3、汇编

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

汇编过程可以调用汇编器as来完成。

4、链接

这个过程是一个复杂的过程,后续学习中会继续记录

时间: 2024-09-30 19:08:44

程序员的自我修养笔记之一--被隐藏的过程的相关文章

程序员的自我修养笔记

1,为什么内存需要分段和分页机制? 早起的计算机中,程序都是直接运行在物理内存上的.这样做有几个问题: 1)地址空间不隔离,计算机的安全性和稳定性没有办法保证,由于所有的程序都可以访问物理内存,恶意的程序可以很容易修改其他程序的内容,达到破坏的目的. 2)内存使用效率低,当前执行的程序(列入进程A)必须被整个装载到内存中执行,如果需要执行另一个程序时,发现内存空间不足,则需要将进程A的数据整体换出到磁盘. 3)程序运行的地址不确定 为了解决上述的三个问题,引入了虚拟地址.分段和分页的概念. 有了

程序员的自我修养 学习笔记(1)

本文源自在学习<程序员的自我修养>中的心得体会. 对于底层系统程序开发者来说,硬件平台可以抽象为三个主要部件,CPU.内存.I/O控制器. 早期的计算机没有复杂的图形功能,CPU和内存之间的频率差异不大,它们都是连接在同一个bus上面的.其他I/O设备,诸如显示设备.键盘.磁盘等速度比内存.CPU慢很多.为了IO设备与CPU.内存之间的协调通讯,一般每个IO设备商都有相应的IO控制器,早期的硬件结构图如下: 随着技术的进步,CPU的频率越来越高,内存跟不上CPU的速度,他们之间就需要一个转换机

程序员的自我修养 学习笔记(4)

可执行文件只有装载到内存以后才能被CPU执行.程序就将是菜谱,CPU就像是厨师,计算机的其他硬件就像是厨具,整个炒菜的过程就是一个进程.同样的一份菜谱,不同人可以做出来不同的味道.这个类比真是巧妙. Linux下面,进程最大使用3G的虚拟空间 Windows下面,进程最大使用2G的虚拟空间 现在计算机,配置超过4G的内存的电脑已经不是不可能了,在这种情况下,32位CPU能够访问到大于4G的空间吗?如果此空间指的是虚拟地址空间,由于32位CPU的指针只能是32位,最大寻址范围是0~4GB.如果此空

一、《程序员的自我修养》笔记-前言

引子:在linux上写了三年多的c了,平时遇到一些编译和链接的问题仍然很是头痛,感觉很无力,好基友推荐<程序员的自我修养>,趁着周末,速速围观. 先记录下作者在书中抛出来的问题 1.为啥程序是从main函数开始执行? 2.PE/ELF文件存的是啥? 3.如何写一个直接跑在未安装os裸机上的程序? 4.目标文件是啥?链接是啥? 5.链接为啥报错? 6.句柄到底是啥? 7.普通c/c++代码如何被编译成牧宝文件及程序在目标文件中如何存储? 8.目标文件如何被链接器链接到一起,并形成可执行文件? 9

读书笔记:程序员的自我修养-----第一章(综述)

题前:30--45天读完,一周至少3篇读书笔记.不能坚持,不再联系,不再找你. 一. hello world 程序引出的问题,看40天后,再回来看看自己的答案,提升多少. Q1:程序为什么要被编译器编译之后才可以运行?   A1 : 系统执行的机器语言,即二进制文件,程序是文本文件需要编译之后,由链接器链接需要的基本库生成二进制文件. Q2: 编译器在把C语言程序转换成可以执行的机器码的过程中作了什么,怎么做的?   A2: 预处理,汇编器生成汇编文件,编译器生成目标文件,链接器链接生成可执行文

【读书笔记】程序员的自我修养总结(六)

[读书笔记]程序员的自我修养总结(六) 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:这是程序员的自我修养一书的读书总结,随着阅读的推进,逐步增加内容. 本文主要介绍可执行文件的装载与进程 程序与进程的区别 程序是静态的,指的是一些预先编译好的指令和数据集合的一个文件:而进程实际上就是运行着的程序,是动态的. 虚拟地址空间 程序运行起来后将拥有独立的虚拟地址空间 virtual address space,其大小由计算机的硬件平台决定,具体地说是

【读书笔记】程序员的自我修养总结(二)

程序员的自我修养总结(二) 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:这是程序员的自我修养一书的读书总结,随着阅读的推进,逐步增加内容. 由源文件到可执行文件 分为四个步骤: 预处理 处理源代码中以#开始的预编译指令,进行宏定义展开,处理所有条件预编译指令,将被包含文件插入到预编译指令的位置,删除所有注释,添加行号及文件标识,保留#pragma编译器指令,因为编译器需用到. 编译 进行一系列词法分析,语法分析,语义分析及优化后生成汇编代码文件

读书笔记:程序员的自我修养-----第三章(目标文件)

一 .目标文件格式 1. PE(Portabel Executable) 2. ELF (Executable Linkable Format) : 可重定位.可执行.共享目标文件.核心转储文件 思考: 弱符号和弱引用   VS   回调函数 __attrbute__ ((weakref)) void foo( ); int main() { if( foo ) foo(); } 可以被用户的强符号覆盖: 读书笔记:程序员的自我修养-----第三章(目标文件)

C++程序员的自我修养–读书笔记

 1:注意不要反回指向栈内存的指针或引用,因为在函数返回时改内存已经被销毁了 2:C/C++没有办法知道指针所指的内存容量大小 当数组作为参数传递时,数组将退化成相同类型的指针 不要指望要指针参数去申请动态内存,因为函数会为产生一个临时变量指向参数的内存,当函数内分配内存时,将内存的地址赋给了临时参数,而没有给实参赋值,所有实参没有发生任何变化,应该修改的是指针所指的内容,而不是修改指针的指向,所有可以用指向指针的指针 3:重载和内联机制既可用于全局函数也可用于类的成员函数,const和vi