关于源程序到可运行程序的过程

wzzkaifa wzzkaifa     2022-09-14     342

关键词:

源程序,是指未经编译的,依照一定的程序设计语言规范书写的,人类可读的文本文件,我们通常理解为源程序就是我们所写好的代码。
可运行程序。我们常说的.exe程序,能够运行程序。完毕计算机功能。在C语言中,.c文件就是所谓的源文件,接下来,我们剖析一下,源程序到可运行程序的过程。

在这个过程中。会发生例如以下的变化:

技术分享

.c文件生成.obj文件的过程,我们称为编译。.obj文件生成到.exe文件的过程,我们称为链接。
在这里首先生成的.obj文件就是一个是程序编译生成的二进制文件。再后来,当.exe文件生成以后.obj文件就会被删除。
事实上。.c文件生成.exe文件的过程总共是经历了预处理,编译,汇编,链接,这四个过程。

- 1.预编译

事实上预编译就是我们所说的预处理。


在过程中,第一个进行的是预编译的过程。
为了接下来能够解释的更加清楚,我们将用linux平台下的gcc编译器解释。
在这里我们先书写一个非常easy的程序来介绍:
首先我们写了这样一个程序

#include<stdio.h>
int main()
{
        printf("hello");
        return 1;
}

技术分享
我们将这个程序写到test.c中去,这里我们能够直接编译得到:

技术分享

接下来。我们一步步具体讨论下当中发生的:

第一步发生的是预编译,在这我们使用-E指令,使用这个指令会使程序仅仅进行到预编译指令。

经过预编译指令后的会生成一个.i文件,所以我们接下来就把预编译的情况放到test.i文件里。

技术分享

在预编译的过程中。主要处理源码中的预处理指令。引入头文件,去除凝视,处理全部的条件编译指令,宏的替换,加入行号,保留全部的编译器指令。

技术分享

这就是预编译后得到的结果
所以当进行预编译以后的文件里将不再存在宏,全部的宏都已经被替代。

当我们我们想要推断宏是否正确或者头文件包括是否正确的时候,我们也能够通过预编译来查看。

- 2.编译

在预处理结束后,我们所要进行的就是编译。编译过程所进行的是对预处理后的文件进行语法分析。词法分析,语义分析,符号汇总,然后生成汇编代码。

在这里我们使用linux的-s命令。这能够得到汇编输出文件test.s
技术分享
打开以后的结果是:

技术分享

从结果我们能够知道,得到的是汇编代码。

- 3.汇编

这里的汇编所说的是一个过程,将汇编代码转成二进制文件。二进制文件就能够让机器来读取。每一条汇编语句都会产生一句机器语言
这里採用的 -O指令
技术分享
在这终于会生成一个重定位目标文件 .o文件。这就好比windows下的.obj文件。这里生成的目标文件里面就是二进制文件。另外,在这须要注意的是,会形成符号表,给这些符号会分配虚拟地址。

- 4.链接

链接,事实上就是将二进制文件链接称为一个可运行的指令。
链接所完毕的任务是合并段表,然后把符号表合并而且对符号表进行重定位。

所谓合并段表。源码编译生成的a.out会包括非常多段。数据段文本段bss段等等,这些段是合并出来的,在编译过程中划分出来出来的,不同的数据会相应到不同的段中。在.o文件里事实上已经发生了分段。

符号表合并和重定位说的是最后仅仅生成了一个符号表。这个符号表是由前面汇编形成的多个符号表进行合并。

在这里不在同一个符号表的符号,要对他们进行重定位。
















c/c++-从代码到可执行程序的过程

(1)预编译主要处理源代码文件中的以“#”开头的预编译指令。处理规则见下:删除所有的#define,展开所有的宏定义。处理所有的条件预编译指令,如“#if”、“#endif”、“#ifdef”、“#elif”和“#else”。处... 查看详情

关于docker运行java程序jvm配置参数使用jconsole的简单量化过程

1.如果服务可以本地启动那么尽量在本地进行参数预估2.如果服务不能本地启动,可以使用远程连接方式进行预估 3.衡量要点:Java程序运行大致分为三块:堆内存,非堆内存(虚拟机栈,方法区,本地方法栈,程序计数器),堆外内存.docker容... 查看详情

源代码到可执行程序的过程详解:预编译编译汇编链接(代码片段)

1、gcc编译过程分解(1)首先是将.c源文件和.h头文件经过预编译(cpp是预编译器),得到.i文件,主要是进行的一些替换工作;(2)将.i文件经过编译器(gcc)处理,得到.s汇编文件,现在文件内容已经从C语言编程了汇编... 查看详情

关于多线程的名词解释

并发与并行并发:指两个或多个事件在同一个时间段内发生。并行:指两个或多个事件在同一时刻发生(同时发生)。线程和进程进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同... 查看详情

gopart7反射

...译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分,在运行程序时,程序无法获取自身的信息)支持反射的语言可以在程序编译期间将变量的反射信息,如字段名称、类型等信息整合到可执行文件中,并给程... 查看详情

程序的编译过程

...1).静态链接在链接期,将静态链接库中的内容直接装填到可执行程序中。在程序执行时,这些代码都会被装入该进程的虚拟地址空间中。优点:运行速度快并且不依赖外部环境,因为在可执行程序中已经具备了所有执行程序所... 查看详情

一个c++源文件从文本到可执行文件经历的过程(代码片段)

一个C++源文件从文本到可执行文件经历的过程以HelloWorld为例进行说明首先我们编写一个cpp源程序test.cpp#include<iostream>usingnamespacestd;intmain()cout<<"helloworld"<<endl;return0;使用g++编译命令时g++-otesttest.cppGcc编 查看详情

从源代码到可执行程序:四个步骤与详解(代码片段)

...orld");return0;编译运行一气呵成。而每当有人问起:从源码到可执行程序有哪些步骤,大多数程序员面对这个问题也能脱口而出:预处理(Prepressing)、编译(Compilation)、汇编(Assembly)和链接(L 查看详情

关于软件工程

  关于软件工程一些简单的记录。  首先是一款软件的开发整体流程:  1,需求分析和定义;2,软件设计;3,程序编写;4,软件测试;5,运行/维护。  每个过程得存在都拥有存在的意义:  需求的分析可以全面的了... 查看详情

库的简介和分类

一、库的分类:  静态库:库中代码被嵌入到可执行程序或动态库中,扩展名为“.lib”  动态库:库中代码不被嵌入到可执行程序或其它动态库中,只在运行时加载,扩展名为“.dll”  简介:    1)由于静态库是将... 查看详情

关于java中异常的叙述正确的是:()a.异常是程序编写过程中代码的语法错误

关于Java中异常的叙述正确的是:()A.异常是程序编写过程中代码的语法错误B.异常是程序编写过程中代码的逻辑错误C.异常出现后程序的运行马上中止D.异常是可以捕获和处理的D是对的异常有很多原因有可能语法有可能逻... 查看详情

从源代码到可执行文件(代码片段)

请简述程序从源代码到可执行程序的过程,面试经常会被问到!这是一个屡见不鲜的问题,总而言之就如下四个过程:预处理比如有test.c源文件,内容如下:#include<stdio.h>/*主函数*/intmain(void) printf("h... 查看详情

从源代码到可执行文件(代码片段)

请简述程序从源代码到可执行程序的过程,面试经常会被问到!这是一个屡见不鲜的问题,总而言之就如下四个过程:预处理比如有test.c源文件,内容如下:#include<stdio.h>/*主函数*/intmain(void) printf("h... 查看详情

dll加载遇到的问题

...加载和显式加载。隐式加载在编译的时候就将dll文件编译到可执行文件中去,程序发布的时候可以不用讲dll带着.缺点是,这样编译出来后,程序会很大。显式加载是指在程序运行过程中,需要用到dll里的函数时,再动态加载dll到内存... 查看详情

go-反射(代码片段)

...译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。支持反射的语言可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件... 查看详情

关于docker运行java程序jvm配置参数使用jconsole的简单量化过程

1.如果服务可以本地启动那么尽量在本地进行参数预估2.如果服务不能本地启动,可以使用远程连接方式进行预估 3.衡量要点:Java程序运行大致分为三块:堆内存,非堆内存(虚拟机栈,方法区,本地方法栈,程序计数器),堆外内存.docker容... 查看详情

关于整个编译过程和库文件的问题

论述1在C中编译器单独编译(Compile)每个源文件(.c)生成相应的目标文件(.obj)链接器链接(Link)各个目标文件(.obj)和资源文件(.res)生成可执行文件(.exe)其中,obj是Complie的产物,同时也是Link的对象,而exe是Link的产物问题1(可多选)静... 查看详情

flask使用程序工厂函数和蓝本中实现程序功能

...这个问题的解决方法是延迟创建程序实例,把创建过程移到可显式调用的工厂函数中。这种方法不仅可以给脚本留出配置程序的时间,还能够创建多个程序实例,这些实例 查看详情