• C程序生成原理


    • 目标文件:

    1. 可执行目标文件: 可以直接在内存中执行;

    2. 可重定向目标文件: 可与其他可重定向目标文件在链接阶段合并, 创建一个可执行目标文件;

    3. 共享目标文件: 可以在运行时被动态加载进内存并链接;

    • 静态连接器

    以一组可重定向目标文件为输入, 生成一个完全链接的可执行目标文件作为输出。 链接器主要完成以下两
    个任务:
    1. 符号解析: 每个符号对应于一个函数、 一个全局变量或一个静态变量, 符号解析的目的是将每个符号引用与一个
    符号定义关联起来。
    2. 重定位: 编译器和汇编器生成从地址 0 开始的代码和数据节, 链接器通过把每个符号定义与一个内存位置关联
    起来, 从而重定位这些节, 然后修改所有对这些符号的引用, 使得它们指向这个内存位置。

    • 动态链接:

    静态库有以下两个问题:
    当静态库更新时那么整个程序都要重新进行链接;
    对于 printf 这种标准函数库, 如果每个程序都要有代码, 这会极大浪费资源。
    共享库是为了解决静态库的这两个问题而设计的, 在 Linux 系统中通常用 .so 后缀来表示, Windows 系统上它
    们被称为 DLL。 它具有以下特点:
    1. 在给定的文件系统中一个库只有一个 .so 文件, 所有引用该库的可执行目标文件都共享这个文件, 它不会被复
    制到引用它的可执行文件中;
    2. 在内存中, 一个共享库的 .text 节的一个副本可以被不同的正在运行的进程共享。

    前处理

    这就是所有这些#defines#includes的含义

    C预处理是一个非常简单的过程:剪切粘贴。

    当预处理器看到以下MyCode.c时:

    #include "MyHeader.h"
    
    void main(){
        FunctionDefinedInHeader();
    }
    

    ,只需打开文件MyHeader.h,然后将其内容粘贴到MyCode.c中:

    
    // Begin of MyCode.c
    // Begin of MyHeader.h
    #ifndef MYHEADER_H
    #define MYHEADER_H
    
    void FunctionDefinedInHeader(); // Declare the function
    
    # endif
    // End of MyHeader.h
    
    void main(){
        FunctionDefinedInHeader(); // Use it
    }
    
    // End of MyCode
    

    同样地,#定义 s的cut'n粘贴的#if s的分析和潜在的除去等

    在此步骤的最后,我们有一个预处理的C ++文件,没有任何#define,#if,#ifdef,#include,可以进行编译了。

    汇编

    编译器将C ++代码转换为CPU可以直接理解的表示形式。例如,以下代码:

    int i=3;
    int j=4*i+2;
    

    将被翻译为:x86操作码。

    
    mov         dword ptr [i],3
    mov         eax,dword ptr [i]
    lea         ecx,[eax*4+2]
    mov         dword ptr [j],ecx
    

    每个.cpp文件是分别编译的,结果二进制代码写在.o / .obj文件中。

    请注意,我们还没有可执行文件:还需要执行一个步骤。

    连结中

    链接器获取所有二进制代码(您的代码,以及来自外部库的代码),并生成最终的可执行文件。一些注意事项:

    • 库具有.lib扩展名。
    • 有些库是静态的这意味着.lib包含所有需要的x86操作码。
    • 一些库是动态的(也称共享)。这意味着.lib不包含任何x86代码。它只是说“我发誓功能FooBarWhatsNot将在运行时可用”。

    链接器运行后,您将拥有一个可执行文件(Windows上为.exe,Unix上为.nothing_at_all):

    运行

    启动可执行文件时,操作系统将打开.exe,然后将x86操作码放入内存。如前所述,某些代码目前尚不可用:动态库中的代码。但是链接器很好,可以说在哪里寻找它:.exe清楚地表明glClearColor函数是在OpenGL32.dll中实现的。

    Windows将愉快地打开.dll并找到glClearColor:

    有时找不到.dll,可能是因为您搞砸了安装过程,并且程序无法运行。

  • 相关阅读:
    一个maven问题
    zz 聊聊并发(七)——Java中的阻塞队列
    聊聊并发(六)
    jvm 内存参数
    zz 聊聊并发(五)
    zz 聊聊并发(四)
    zz 聊聊并发(三)
    zz 聊聊并发(二)
    zz 聊聊并发(一)
    JQuery中$.ajax()方法参数详解
  • 原文地址:https://www.cnblogs.com/wwhhgg/p/12620257.html
Copyright © 2020-2023  润新知