gcc 编译c文件的几个过程

https://www.cnblogs.com/zhangpengshou/p/3587751.htmlhtml

http://m.elecfans.com/article/663750.htmllinux

https://www.cnblogs.com/LiuYanYGZ/p/5548855.html函数

https://blog.csdn.net/qq_33160790/article/details/78887349性能

 

c语言编译分为4个过程:优化

1:预编译:预编译作的事情为:把伪指令转换为实际指令  命令 gcc -Eui

  a:#define a b spa

  b:#条件编译指令,如#ifdef,#ifndef,#else,#elif,#endif等操作系统

  c:#include 头文件加入到编译的文件中.net

  d:一些符号处理如file local 等等;翻译

 

# 1 "/usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/stddef.h" 1 3 4
# 211 "/usr/lib/gcc/x86_64-redhat-linux/4.4.7/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 35 "/usr/include/stdio.h" 2 3 4

# 1 "/usr/include/bits/types.h" 1 3 4
# 28 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/wordsize.h" 1 3 4
# 29 "/usr/include/bits/types.h" 2 3 4


typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;


typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;

typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;

 

 

 

能够看出一个很小的程序通过编译之后把全部的头文件包含进来都是很大的

2:编译    命令是  gcc -S

  把预编译好的文件逐条转化为汇编语言

  优化阶段,通过预编译获得的输出文件中,只有常量;如数字、字符串、变量的定义,

  以及c语言的关键字,如main,if,else,for,while,{,}, +,-,*,\等等。

  编译程序所要做得工做就是经过词法分析和语法分析,在确认全部的指令都符合语法规则以后,

  将其翻译成等价的中间代码表示或汇编代码。以下都是汇编代码;操做寄存器

 .file   "test7.c"
        .text
.globl power
        .type   power, @function
power:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    %edi, -20(%rbp)
        movl    %esi, -24(%rbp)
        movl    $1, -8(%rbp)
        movl    -20(%rbp), %eax
        movl    %eax, -4(%rbp)
        jmp     .L2
.L3:
        movl    -4(%rbp), %eax
        movl    -20(%rbp), %edx
        imull   %edx, %eax
        movl    %eax, -20(%rbp)
        addl    $1, -8(%rbp)

 

3:汇编  命令gcc -c

  将.c文件直接编译成.o的二进制文件:

 

4:连接 命令是 gcc *.c    连接命令是ld 连接的时候要考虑代码和数据所要放的内存位置,能够经过连接脚原本设置(这里下次课再说)

 

连接程序的主要工做就是将有关的目标文件彼此相链接,也即将在一个文件中引用的符号同该符号在另一个文件中的定义链接起来,使得全部的这些目标文件成为一个可以诶操做系统装入执行的统一总体。

 

根据开发人员指定的同库函数的连接方式的不一样,连接处理可分为两种:

 

(1)静态连接

 

在这种连接方式下,函数的代码将从其所在地静态连接库中被拷贝到最终的可执行程序中。这样该程序在被执行时这些代码将被装入到该进程的虚拟地址空间中。静态连接库其实是一个目标文件的集合,其中的每一个文件含有库中的一个或者一组相关函数的代码。

 

(2) 动态连接

 

在此种方式下,函数的代码被放到称做是动态连接库或共享对象的某个目标文件中。连接程序此时所做的只是在最终的可执行程序中记录下共享对象的名字以及其它少许的登记信息。在此可执行文件被执行时,动态连接库的所有内容将被映射到运行时相应进程的虚地址空间。动态连接程序将根据可执行程序中记录的信息找到相应的函数代码。

 

对于可执行文件中的函数调用,可分别采用动态连接或静态连接的方法。使用动态连接可以使最终的可执行文件比较短小,而且当共享对象被多个进程使用时能节约一些内存,由于在内存中只须要保存一份此共享对象的代码。但并非使用动态连接就必定比使用静态连接要优越。在某些状况下动态连接可能带来一些性能上损害。

=====================

gcc -o 指定文件名  如 gcc -c hello.c  -o hello.a

gcc -M  只输出编译信息不编译

gcc -MM  只输出编译信息不编译

相关文章
相关标签/搜索