<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Executable on TouchingFish.top</title><link>https://touchingfish.top/tags/executable/</link><description>Recent content in Executable on TouchingFish.top</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 01 May 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://touchingfish.top/tags/executable/index.xml" rel="self" type="application/rss+xml"/><item><title>从源代码到可执行程序</title><link>https://touchingfish.top/2020/journey-to-c-language/</link><pubDate>Fri, 01 May 2020 00:00:00 +0000</pubDate><guid>https://touchingfish.top/2020/journey-to-c-language/</guid><description>&lt;p&gt;编程是和计算机对话的过程。我们按照计算机能理解的方式，用抽象的编程语言来描述算法和逻辑，给计算机下达指令，让它完成工作。&lt;/p&gt;
&lt;p&gt;在 C 语言的程序开发过程中，预处理、编译和汇编是将源代码转化为可执行程序的几个关键阶段。理解它们之间的关系有助于更好地理解C语言的编译过程。下面将详细介绍这几个阶段的作用及其相互关系。&lt;/p&gt;
&lt;h2 id="预处理"&gt;预处理&lt;/h2&gt;
&lt;p&gt;预处理（Preprocessing）是 C 语言编译过程中的第一个阶段。在这个阶段，C 编译器的预处理器（Preprocessor）处理代码中的预处理指令，如 &lt;code&gt;#include&lt;/code&gt;、&lt;code&gt;#define&lt;/code&gt;、&lt;code&gt;#ifdef&lt;/code&gt; 等。这些指令通常用来管理宏定义、文件包含、条件编译等。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;宏替换：将所有定义的宏替换为相应的代码。例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#define PI 3.14
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在程序中所有出现 &lt;code&gt;PI&lt;/code&gt; 的地方，都会被替换为 &lt;code&gt;3.14&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;文件包含：将 &lt;code&gt;#include&lt;/code&gt; 指定的头文件内容插入到当前文件中。例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;会将 &lt;code&gt;stdio.h&lt;/code&gt; 文件的内容包含到当前源文件中。在一段代码中，通常会在首行引用头文件，指令告诉 &lt;code&gt;CPP&lt;/code&gt; 从系统库中获取 &lt;code&gt;stdio.h&lt;/code&gt;，并拷贝其中的文本到当前的源文件里。（&lt;strong&gt;乱用头文件会影响编译的效率&lt;/strong&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;条件编译：根据条件判断是否编译某些代码段。例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#ifdef DEBUG
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Debug mode&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;只有在定义了 &lt;code&gt;DEBUG&lt;/code&gt; 宏的情况下，&lt;code&gt;printf&lt;/code&gt; 语句才会被编译。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;预处理后的输出是一个扩展的源文件，其中所有的预处理指令都已经被处理和替换。这个文件将传递给编译器的下一阶段。&lt;/p&gt;
&lt;h2 id="编译"&gt;编译&lt;/h2&gt;
&lt;p&gt;编译（Compilation）是将预处理后的 C 代码转换为汇编代码的过程。编译器会检查代码的语法和结构，优化代码，并生成汇编代码。&lt;/p&gt;
&lt;p&gt;在这个阶段，编译器会执行以下操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语法分析：检查代码的语法是否正确，确保符合C语言的语法规则。&lt;/li&gt;
&lt;li&gt;语义分析：检查代码的语义是否合理，例如变量类型的正确性、函数调用的合法性等。&lt;/li&gt;
&lt;li&gt;优化：编译器可能会对代码进行优化，以提高生成代码的运行效率。&lt;/li&gt;
&lt;li&gt;生成汇编代码：将C语言的代码转换为特定硬件架构的汇编语言。例如，&lt;code&gt;gcc&lt;/code&gt; 编译器将生成 &lt;code&gt;.s&lt;/code&gt; 文件（包含汇编代码）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;汇编代码是一种低级语言，更接近机器代码，但仍然是人类可读的（如 &lt;code&gt;MOV&lt;/code&gt;, &lt;code&gt;ADD&lt;/code&gt; 等指令）。&lt;/p&gt;
&lt;h2 id="汇编"&gt;汇编&lt;/h2&gt;
&lt;p&gt;汇编（Assembly）是将汇编代码转换为机器代码的过程。在这个阶段，汇编器（Assembler）会将汇编代码翻译成目标机器的二进制指令，这些指令可以直接在处理器上执行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生成目标文件：汇编器将生成一个目标文件（通常是 &lt;code&gt;.o&lt;/code&gt; 或 &lt;code&gt;.obj&lt;/code&gt; 文件），它包含了机器代码以及一些调试和链接信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目标文件最终会被打包成可执行文件（例如 &lt;code&gt;.exe&lt;/code&gt; 文件），可以直接在计算机上运行。&lt;/p&gt;
&lt;h2 id="关系与流程"&gt;关系与流程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;预处理是编译的第一步，处理宏、头文件等预处理指令，生成一个纯C语言的源代码文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编译阶段将预处理后的源代码翻译为汇编代码，这个过程中包括了语法检查、优化等重要步骤。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;汇编阶段将汇编代码转换为机器代码，生成目标文件。&lt;/p&gt;</description></item></channel></rss>