c代码如何转换成可以在硬件上运行程序.docxVIP

  • 14
  • 0
  • 约2.22千字
  • 约 6页
  • 2022-03-01 发布于浙江
  • 举报

c代码如何转换成可以在硬件上运行程序.docx

PAGE PAGE 1 c代码如何转换成可以在硬件上运行程序 过程图解如下: 编译过程又可以分成两个阶段:编译和汇编。 编译 编译是读取源程序((字符)流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程包含两个主要阶段: 主要是以下几方面的处理: (1)宏定义指令,如 #define a b 对于这种伪指令,预编译所要做的是将程序中的全部a用b替换,但作为字符串常量的 a则不被替换。还有 #undef,则将取消对某个宏的定义,使以后该串的消失不再被替换。 (2)条件编译指令,如#(if)def,#ifndef,#else,#elif,#endif等。 这些伪指令的引入使得程序员可以通过定义不同的宏来打算编译程序对哪些代码进行处理。预编译程序将依据有关的文件,将那些不必要的代码过滤掉。 (3) 头文件包含指令,如#include FileName或者#include 汇编 汇编实际上指把汇编语言代码翻译成目标机器指令的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。目标文件中所存放的也就是与源程序等效的目标的机器语言代码。目标文件由段组成。通常一个目标文件中至少有两个段: 代码段:该段中所包含的主要是程序的指令。 该段一般是可读和可执行的,但一般却不行写。 数据段:主要存放程序中要用到的各种全局变量或静态的数据。一般数据段都是可读,可写,可执行的。 UNIX环境下主要有三种类型的目标文件: (1)可重定位文件 其中包含有适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。 (2)共享的目标文件 这种文件存放了适合于在两种上下文里链接的代码和数据。第一种是链接程序可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个 目标文件;其次种是动态链接程序将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象。 (3)可执行文件 它包含了一个可以被操作系统创建一个进程来执行之的文件。汇编程序生成的实际上是第一种类型的目标文件。对于后两种还需要其他的一些处理方能得到,这个就是链接程序的工作了。 链接过程 由汇编程序生成的目标文件并不能马上就被执行,其中可能还有很多没有解决的问题。 例如,某个源文件中的函数可能引用了另一个源文件中定义的某个符号(如变量或者函数调用等);在程序中可能调用了某个库文件中的函数,等等。全部的这些问题,都需要经链接程序的处理方能得以解决。 链接程序的主要工作就是将有关的目标文件彼此相连接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得全部的这些目标文件成为一个能够诶操作系统装入执行的统一整体。 依据开发人员指定的同库函数的链接方式的不同,链接处理可分为两种: (1)静态链接 在这种链接方式下,函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态链接库实际上是一个目标文件的集合,其中的每个文件含有库中的一个或者一组相关函数的代码。 (2) 动态链接 在此种方式下,函数的代码被放到称作是动态链接库或共享对象的某个目标文件中。链接程序此时所作的只是在最终的可执行程序中记录下共享对象的名字以及其它少量的登记信息。在此可执行文件被执行时,动态链接库的全部内容将被映射到运行时相应进程的虚地址空间。动态链接程序将依据可执行程序中记录的信息找到相应的函数代码。 对于可执行文件中的函数调用,可分别采纳动态链接或静态链接的方法。使用动态链接能够使最终的可执行文件比较短小,并且当共享对象被多个进程使用时能节省一些内存,由于在内存中只需要保存一份此共享对象的代码。但并不是使用动态链接就肯定比使用静态链接要优越。在某些状况下动态链接可能带来一些性能上损害。 我们在(Linux)使用的gcc编译器便是把以上的几个过程进行捆绑,使用户只使用一次命令就把编译工作完成,这的确便利了编译工作,但对于初学者了解编译过程就很不利了,下图便是gcc代理的编译过程: 从上图可以看到: 预编译 将.c 文件转化成 .i文件 使用的gcc命令是:gcc –E 对应于预处理命令cpp 编译 将.c/.h文件转换成.s文件 使用的gcc命令是:gcc –S 对应于编译命令 cc –S 汇编 将.s 文件转化成 .o文件 使用的gcc 命令是:gcc –c 对应于汇编命

文档评论(0)

1亿VIP精品文档

相关文档