<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Compile on pemako</title>
    <link>http://pemako.cn/tags/compile/</link>
    <description>Recent content in Compile on pemako</description>
    <image>
      <title>pemako</title>
      <url>http://pemako.cn/images/papermod-cover.png</url>
      <link>http://pemako.cn/images/papermod-cover.png</link>
    </image>
    <generator>Hugo -- 0.146.6</generator>
    <language>en</language>
    <lastBuildDate>Thu, 09 Apr 2026 20:00:00 +0800</lastBuildDate>
    <atom:link href="http://pemako.cn/tags/compile/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>程序基础知识</title>
      <link>http://pemako.cn/posts/program-fundamentals/</link>
      <pubDate>Thu, 09 Apr 2026 20:00:00 +0800</pubDate>
      <guid>http://pemako.cn/posts/program-fundamentals/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;对称多处理器 (SMP, Symmetrical Multi-Processing)&lt;/li&gt;
&lt;li&gt;多核处理器（Multi-core Processor）&lt;/li&gt;
&lt;li&gt;应用程序接口（Application Programming Interface）&lt;/li&gt;
&lt;li&gt;系统调用接口（System call Interface）&lt;/li&gt;
&lt;li&gt;软件中断（Software Interrupt）&lt;/li&gt;
&lt;li&gt;硬件规格（Hardware Specification）&lt;/li&gt;
&lt;li&gt;多道程序（Multiprogramming）&lt;/li&gt;
&lt;li&gt;分时系统（Time-Sharing System）&lt;/li&gt;
&lt;li&gt;多任务系统（Multi-tasking System）&lt;/li&gt;
&lt;li&gt;进程（Process）&lt;/li&gt;
&lt;li&gt;抢占式（Preemptive）&lt;/li&gt;
&lt;li&gt;硬件驱动（Device Driver）&lt;/li&gt;
&lt;li&gt;扇区（Sector）&lt;/li&gt;
&lt;li&gt;LBA（Logical Block Address）即整个硬盘中所有的扇区从0开始编号，一直到最后一个扇区，这个扇区编号叫做逻辑扇区号。逻辑扇区号抛弃了所有复杂的磁道、盘面之类的概念。&lt;/li&gt;
&lt;li&gt;虚拟地址空间（Virtual Address Space）&lt;/li&gt;
&lt;li&gt;物理地址空间（Physical Address Space）&lt;/li&gt;
&lt;li&gt;分段（Segmentation）基本思路是把一段与程序所需要的内存空间大小的虚拟空间映射到某个地址空间&lt;/li&gt;
&lt;li&gt;分页（Paging）基本方法是把地址空间人为地等分成固定大小的页，每一页的大小由硬件决定，或硬件支持多种大小的页，由操作系统选择决定页的大小。&lt;/li&gt;
&lt;li&gt;虚拟页（VP Virtual Page）&lt;/li&gt;
&lt;li&gt;物理页（PP Physical Page）&lt;/li&gt;
&lt;li&gt;磁盘页（DP Disk Page）&lt;/li&gt;
&lt;li&gt;页错误（Page Fault）&lt;/li&gt;
&lt;li&gt;MMU（Memory Management Unit）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;虚拟地址到物理地址的转换&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR 
	CPU --&amp;gt; |Vitual Address| MMU --&amp;gt; |Physical Address| PhysicalMemory
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;线程（Thread）有时被称为轻量级进程（Lightweight Process, LWP）是程序执行流的最小单元。一个标准的线程由线程 ID、当前指令指针（PC）、寄存器集合和堆栈组成。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;线程私有&lt;/th&gt;
          &lt;th&gt;线程之间共享 (进程所有)&lt;/th&gt;
          &lt;th&gt;&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;局部变量&lt;/td&gt;
          &lt;td&gt;全局变量&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;函数的参数&lt;/td&gt;
          &lt;td&gt;堆上的数据&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;TLS(Thread Local Storage)数据&lt;/td&gt;
          &lt;td&gt;函数里的静态变量&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;程序代码，任何线程都有权利读取病执行任何代码&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;/td&gt;
          &lt;td&gt;打开的文件，A线程打开的文件可以由B线程读写&lt;/td&gt;
          &lt;td&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;在单处理器对应多线程的情况下，并发是一种模拟出来的状态。操作系统会让这些多线程程序轮流执行，每次仅执行一小段时间（通常是几十到几百毫秒），这样每个线程就“看起来”在同时执行。这样的一个不断在处理器上切换不同的线程的行为称之为&lt;strong&gt;线程调度&lt;/strong&gt; （Thread Schedule）。在线程调度中，线程通常拥有至少三种状态&lt;/p&gt;</description>
    </item>
    <item>
      <title>静态链接</title>
      <link>http://pemako.cn/posts/static-linking/</link>
      <pubDate>Thu, 09 Apr 2026 20:00:00 +0800</pubDate>
      <guid>http://pemako.cn/posts/static-linking/</guid>
      <description>&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#include&lt;/span&gt; &lt;span class=&#34;cpf&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class=&#34;cp&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nf&#34;&gt;printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Hello World&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gcc hello.c
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./a.out
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面的过程分解为4个步骤，分别是&lt;strong&gt;预处理&lt;/strong&gt;（Prepressing）、&lt;strong&gt;编译&lt;/strong&gt;（Compilation）、&lt;strong&gt;汇编&lt;/strong&gt;（Assembly）和&lt;strong&gt;链接&lt;/strong&gt;（Linking）。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-mermaid&#34; data-lang=&#34;mermaid&#34;&gt;flowchart LR
    src[&amp;#34;Source Code\nhello.c&amp;#34;]
    header[&amp;#34;Header Files\nstdio.h\n....&amp;#34;]
    lib[&amp;#34;Static Library\nlibc.a\n...&amp;#34;]
    cpp[&amp;#34;Preprocessing\n(cpp)&amp;#34;]
    hi[&amp;#34;Preprocessed\nhello.i&amp;#34;]
    gcc[&amp;#34;Compilation\n(gcc)&amp;#34;]
    hs[&amp;#34;Assembly\nhello.s&amp;#34;]
    as[&amp;#34;Assembly\n(as)&amp;#34;]
    ho[&amp;#34;Object File\nhello.o&amp;#34;]
    ld[&amp;#34;Linking\n(ld)&amp;#34;]
    out[&amp;#34;Executable\na.out&amp;#34;]

    src --&amp;gt; cpp
    header --&amp;gt; cpp
    cpp --&amp;gt; hi --&amp;gt; gcc --&amp;gt; hs --&amp;gt; as --&amp;gt; ho --&amp;gt; ld --&amp;gt; out
    lib --&amp;gt; ld
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;预编译&#34;&gt;预编译&lt;/h2&gt;
&lt;p&gt;第一步与预编译的过程相当于如下命令（-E 表示只进行预编译）
&lt;code&gt;gcc -E hello.c -o hello.i&lt;/code&gt; 或 &lt;code&gt;cpp hello.c &amp;gt; hello.i&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;预编译的处理规则如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将所有的 &lt;code&gt;#define&lt;/code&gt; 删除，并且展开所有的宏定义&lt;/li&gt;
&lt;li&gt;处理所有条件预编译指令，比如 &lt;code&gt;#if&lt;/code&gt;  &lt;code&gt;#ifdef&lt;/code&gt; &lt;code&gt;#elif&lt;/code&gt; &lt;code&gt;#else&lt;/code&gt; &lt;code&gt;#endif&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;处理 &lt;code&gt;#include&lt;/code&gt; 预编译指令，将被包含的文件插入到该预编译指令的位置。这个过程是递归进行的，也就是说被包含的文件可能还包含其他文件&lt;/li&gt;
&lt;li&gt;删除所有的注释 &lt;code&gt;//&lt;/code&gt; 和 &lt;code&gt;/**/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;添加行号和文件名标识，比如 #2 &amp;ldquo;hello.c&amp;rdquo; 2, 已便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号&lt;/li&gt;
&lt;li&gt;保留所有的 &lt;code&gt;#pragma&lt;/code&gt; 编译指令，因为编译器需要使用它们&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;编译&#34;&gt;编译&lt;/h2&gt;
&lt;p&gt;编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。上面的编译过程相当于 &lt;code&gt;gcc -S hello.i -o hello.s&lt;/code&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
