GCC编译器(1)

2023-11-05

1.GCC简介

GCC(GNU Compiler Collection)是一套功能强大、性能优越的编程语言编译器,它是GNU计划的代表作品之一。GCC是Linux平台下最常用的编译器,GCC原名为GNU C Compiler,即GNU C语言编译器,随着GCC支持的语言越来越多,它的名称也逐渐变成了GNU Compiler Collection。下面对GCC的基本使用方法进行介绍。

2.基本选项

GCC编译器的基本选项如下表:

类型 说明
-E 预处理后即停止,不进行编译、汇编及连接
-S 编译后即停止,不进行汇编及连接
-c 编译或汇编源文件,但不进行连接
-o file 指定输出文件file

我们都知道程序的编译要经历预处理、编译、汇编以及连接4个阶段。在预处理阶段,主要处理C语言源文件中的#ifdef、#include、以及#define等命令。在与处理过程中,GCC会忽略掉不需要预处理的输入文件,该阶段会生成中间文件*.i。

对如下的源程序example.c:

1
2
3
4
5
6
7
8
#include <stdio.h>
int  main()
{
     int  x;
     for (x=1;x<=10;x++)
     printf ( "%d\n" ,x);
     return  0;
}

使用如下命令对上面的源文件进行预处理。

$ gcc -E example.c -o example.i

上面使用了两个选项:-E和-o file,其中-E表示在预处理结束后即停止编译过程;-o指定输出文件问file。前面的选项不同,输出的文件类型也不相同,可能为预处理后的C代码、汇编文件、目标文件或可执行文件,这里即为预处理后的C代码。

预处理后输出文件example.i的内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1 "example.c"
# 1 "<built-in>"
# 1 "<命令行>"
# 1 "example.c"
 
# 1 "/usr/include/stdio.h" 1 3 4
...(中间部分省略)
extern  void  funlockfile ( FILE  *__stream) __attribute__ ((__nothrow__));
# 936 "/usr/include/stdio.h" 3 4
 
# 2 "example.c" 2
int  main()
{
     int  x;
     for (x=1;x<=10;x++)
  printf ( "%d\n" ,x);
     return  0;
}

从上面的代码可以看出,GCC对源文件所包含的头文件stdio.h进行了预处理,由于输出文件example.i比较长,上面只给出了部分内容。

在编译阶段,输入的是中间文件*.i,编译后生成的是汇编语言文件*.s。对应的GCC命令为:

$ gcc -S example.i -o example.s

example.s即为生成的汇编文件,其内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
     .file   "example.c"
     .section    .rodata
.LC0:
     .string "%d\n"
     .text
     .globl  main
     .type   main, @function
main:
.LFB0:
     .cfi_startproc
     pushl   %ebp
     .cfi_def_cfa_offset 8
     .cfi_offset 5, -8
     movl    %esp, %ebp
     .cfi_def_cfa_register 5
     andl    $-16, %esp
     subl    $32, %esp
     movl    $1, 28(%esp)
     jmp .L2
.L3:
     movl    $.LC0, %eax
     movl    28(%esp), %edx
     movl    %edx, 4(%esp)
     movl    %eax, (%esp)
     call    printf
     addl    $1, 28(%esp)
.L2:
     cmpl    $10, 28(%esp)
     jle .L3
     movl    $0, %eax
     leave
     .cfi_restore 5
     .cfi_def_cfa 4, 4
     ret
     .cfi_endproc
.LFE0:
     .size   main, .-main
     .ident  "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
     .section    .note.GNU-stack, "" ,@progbits

上面的语句主要实现了一个for循环,有汇编基础的朋友应该很容易看懂,这里不多介绍了。

上面的例子是在预处理后C代码的基础上进行编译的,其实可以直接从源代码编译,使用的命令为:

$ gcc –s example.c –o example.o

汇编是将输入的汇编语言文件转换为目标代码,可以使用-c选项来完成。对应GCC命令为:

$ gcc –c example.s –o example.o

最后,将生成的目标文件与其他目标文件(或库文件)连接成可执行的二进制代码文件。使用的命令为:

$ gcc example.o –o example

运行example,输出结果如下:

./example

1

2

3

4

5

6

7

8

9

10

以上代码从预处理、编译、汇编以及连接一步步介绍,主要目的是讲解程序编译的整个过程以及GCC的各个选项,其实如果只需要最终的可执行文件,可以直接对源代码进行编译连接,命令如下:

$ gcc example.c –o example

对于一个程序的多个源文件进行编译连接时,可以使用如下格式:

gcc –o test first.c second.c third.c

该命令将同时编译3个源文件,将它们连接成一个可执行文件,名为test。

上面的例子都给出-o选项,如果没有给出该选项,默认的输出结果为:预处理后的C代码被送往标准输出,即输出到屏幕,汇编文件为example.s,目标文件为example.o,而可执行文件问a.out。

3.优化选项

GCC具有优化代码的功能,主要的优化选项包括如下:

  • -O0:不进行优化处理。
  • -O或-O1:进行基本的优化,这些优化在大多数情况下都会使程序执行得更快。
  • -O2:除了完成-O1级别的优化外,还要一些额外的调整工作,如处理器指令调度等,这是GNU发布软件的默认优化级别。
  • -O3:除了完成-O2级别的优化外,还进行循环的展开以及其他一些与处理器特性相关的优化工作。
  • -Os:生成最小的可执行文件,主要用于在嵌入式领域。

一般来说,优化级别越高,生成可执行文件的运行速度也越快,但消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候才考虑对最终生成的代码进行优化。

  • -finline-functions:允许编译器将一些简单的函数在其调用处展开。
  • -funswitch-loops:将循环体中值不改变的变量移到循环体外。

具体的命令格式如下:

$ gcc –O2 –finline-functions example.c –o example

下面给出一个例子来看看GCC优化项的效果,源程序为:example6.c。

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int  main ()
{
     int  x;
     int  sum=0;
     for (x=1;x<=le9;x++)
     {
         sum+=(x*300)/256;
     }
     return  0;
}

首先不加任何优化选项,对上面的源程序进行编译如下:

$ gcc example6.c -o example6

$ time ./example6

real 0m4.750s

user 0m4.696s

sys 0m0.012s

time命令的输出结果由一下3部分组成:

  • real:程序的总执行时间,包括进程的调度、切换等时间。
  • user:用户进行执行的时间。
  • sys:内核执行的时间。

接下来使用优化选项-O2对上面的源程序进行处理:

$ gcc -O2 example6.c -o example6^C

$ time ./example6

real 0m1.473s

user 0m1.460s

sys 0m0.008s

从上面的结果可以看出,程序的性能得到了大幅度的改善。


FROM:  http://www.cnblogs.com/iuices/archive/2011/12/10/2283618.html


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCC编译器(1) 的相关文章

随机推荐

  • 如何在OS X 10.7上开发一个简单的应用教程(一)

    原文 http www raywenderlich com 17811 how to make a simple mac app on os x 10 7 tutorial part 13 原创译文 转载注明出处 http blog csd
  • 汽配企业建设数字化工厂的步骤是什么

    随着信息技术的迅猛发展 汽车行业也面临着数字化转型的迫切需求 汽配企业作为汽车产业链上重要的一环 也需要积极采取措施 建设数字化工厂系统 以适应市场竞争的变化 下面将介绍建设汽配企业数字化工厂的具体步骤 第一步 制定数字化转型策略 汽配企业
  • 小程序 已被代码依赖分析忽略,无法被其他模块引用。你可根据控制台中的【代码依赖分析】告警信息修改代码,或关闭【过滤无依赖文件】功能

    出现以下错误 NO1 刚开始搜网说要在开发工具 右上角 详情 gt 本地设置 gt 上传时过滤无依赖文件 关闭即可 但是并没什么用其实 NO2 只需在 project config json gt setting 里面设置 ignoreUp
  • C++ Template 特化与重载

    特化与重载 1 重载函数模板 与普通函数一样 函数模板也可以重载 在重载函数模板的时候 应该把改变限制在一下两种情况 改变参数的数目或者显示地指定模板参数 除此之外 函数的所有重载版本的声明都应该位于该函数被调用的位置之前 P S 类模板是
  • osgEarth的Rex引擎原理分析(二十三)PagerLoader的traverse过程详解

    目标 十七 中问题48 主要包含两个过程 1 已处理过请求的加载 这是真正意义上的加载 刚创建出来的请求是从缓存或文件没有关联影像 高程等数据的 需要经过多线程处理后才有数据 详见 十七 对于这些处理过的请求 在PagerLoader的更新
  • android好书推荐

    准备买的书籍 一 Android系统级深入开发 移植与调试 作者 韩超 亚马逊 27 5元 电子书 我的csdn资源有 介绍怎样移植android系统到不同嵌入式平台 以android模拟器内核goldfish 高通MSM平台 德州仪器OM
  • C/C++中的结束输入条件判断 (scanf、EOF、getchar()、cin.get()、getline)

    本教程主要适用于一些程序比赛或大公司机试中的输入数据的处理 总的来说 可以分为以下三种情况 情况一 输入的测试样例有多组 每组需要相同逻辑的处理 处理方案 在C语言中可利用scanf d n EOF 在C 中可以使用while cin gt
  • 利用Vulnhub复现漏洞 - Gogs 任意用户登录漏洞(CVE-2018-18925)

    Gogs 任意用户登录漏洞 CVE 2018 18925 Vulnhub官方复现教程 漏洞原理 复现过程 启动环境 漏洞复现 失误原因 Vulnhub官方复现教程 https vulhub org environments gogs CVE
  • CTFSHOW WEB 1-100

    web入门 给她 1 参考文档 https blog csdn net weixin 51412071 article details 124270277 查看链接 sql注入 直接用这里的payload也可以 但是要构造万能密码 把and
  • 2021-05-04

    JAVA替换PDF文字
  • 小皮面板rce漏洞

    适用版本 V1 02版本以下 新版已修补该漏洞 复现 现在官网上的小皮面板 已经修复了该漏洞 所以已经无法用官网的版本来复现漏洞 据我目前不成熟的测试感觉 它在用户名的输入上限制了字符数 所以所以我们的js代码无法写入 小皮面板下载好后 会
  • 基于51单片机的大棚环境土壤湿度光强监测系统proteus仿真原理图PCB

    功能介绍 0 本系统采用STC89C52作为单片机 1 系统实时监测当前温湿度 土壤湿度 环境光强并显示 2 温湿度超过设定阈值范围 蜂鸣器响 同时开启对应控制继电器 3 土壤湿度低于设定下限 开启喷洒 直至达到上限 关闭喷洒 4 环境光强
  • 11、信息收集篇————钟馗之眼使用

    无意中发现了一个巨牛巨牛的人工智能教程 忍不住分享一下给大家 教程不仅是零基础 通俗易懂 小白也能学 而且非常风趣幽默 还时不时有内涵段子 像看小说一样 哈哈 我正在学习中 觉得太牛了 所以分享给大家 点这里可以跳转到教程 前言 ZoomE
  • 力扣26-删除排序数组中的重复项【双指针】

    给定一个排序数组 你需要在 原地 删除重复出现的元素 使得每个元素只出现一次 返回移除后数组的新长度 不要使用额外的数组空间 你必须在 原地 修改输入数组 并在使用 O 1 额外空间的条件下完成 示例 1 给定数组 nums 1 1 2 函
  • STM32使用内部晶振的配置方法

    STM32使用内部晶振的配置方法 首先 STM32使用内部晶振需要在代码里面配置 以STM32RCT6为例 在使用内部晶振的情况下最高运行频率为64Mhz 程序只需要在system stm32f10x c中配置即可 代码如下 复制以下代码覆
  • 启动盘制作

    启动盘 指的是将特殊改造过的精简Windows系统 安装到一个U盘上 上面有各种软件 可以用来调整硬盘分区 安装系统和破解密码 准备一个容量8G以上的U盘 里面的数据必须提前备份 在制作过程中 U盘会被格式化 下载微PE制作软件 建议下载w
  • Golang实现Telnet回音服务器

    码上见 package main import bufio fmt net os strings 服务端连接 func server address string exitChan chan int l err net Listen tcp
  • 【Vue】使用Vue调起摄像头,进行拍照并能保存到本地

    1 使用Vue js 把网页内容Ctrl s保存到本地然后添加到项目中 https cdn jsdelivr net npm vue dist vue jshttps cdn jsdelivr net npm vue dist vue js
  • 最大连续子数组和(一个数组有 N 个元素,求连续子数组的最大和)

    最大连续子数组和 一个数组有 N 个元素 求连续子数组的最大和 例如 1 2 1 和最大的连续子数组为 2 1 其和为 3 输入描述 输入为两行 第一行一个整数n 1 lt n lt 100000 表示一共有n个元素 第二行为n个数 即每个
  • GCC编译器(1)

    1 GCC简介 GCC GNU Compiler Collection 是一套功能强大 性能优越的编程语言编译器 它是GNU计划的代表作品之一 GCC是Linux平台下最常用的编译器 GCC原名为GNU C Compiler 即GNU C语