首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么GCC为几乎相同的C代码生成如此完全不同的程序集?

在这个问题中,GCC(GNU Compiler Collection)是一个编译器套件,用于将高级编程语言(如C、C++、Objective-C、Fortran、Java等)转换为机器代码。GCC为几乎相同的C代码生成如此完全不同的程序集的原因可能有以下几点:

  1. 优化级别:GCC提供了多种优化选项,如-O0(无优化)、-O1(基本优化)、-O2(进一步优化)等。不同的优化级别会导致生成的程序集代码有所不同,因为GCC会根据优化级别选择不同的优化策略。例如,-O2级别的优化可能会导致更高效的程序集代码,但同时也可能增加编译时间。
  2. 目标平台:GCC生成的程序集代码可能会因目标平台的不同而有所差异。不同的平台可能有不同的指令集和性能特点,因此GCC会针对不同的平台生成相应的程序集代码。
  3. 编译器版本:GCC的不同版本可能会采用不同的优化策略和代码生成方法,从而导致生成的程序集代码有所不同。随着GCC版本的更新,可能会引入新的优化技术和改进,从而影响生成的程序集代码。
  4. 编译器后端:GCC使用不同的后端(如GIMPLE或RTL)来生成程序集代码。不同的后端可能会导致生成的程序集代码有所不同,因为它们采用不同的中间表示和优化方法。
  5. 随机因素:在某些情况下,GCC生成的程序集代码可能会因随机因素而有所不同。例如,当使用哈希表或其他数据结构进行优化时,元素的顺序可能会影响生成的程序集代码。

总之,GCC为几乎相同的C代码生成如此完全不同的程序集,主要是因为优化级别、目标平台、编译器版本、编译器后端等多种因素的综合作用。在实际应用中,可以根据具体需求选择合适的优化级别和目标平台,以生成最佳的程序集代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

GCC、ARM-LINUX-GCC、ARM-ELF-GCC浅析

大家好,又见面了,我是全栈君 一、GCC简介: The GNU Compiler Collection,通常简称GCC,是一套由GNU开发编译器为什么是编辑器而不是编译器呢?...因为不同目标机指令是不一样,比如arm跟x86就不一样】 2. gcc-core:顾明之意是GCC核心部分,这部分是只包含c编译器及公共部分,而对其他语言【C++、Ada等】支持包需要另外安装...例如,要使用交叉工具链ARM机器编译简单Hello World程序,你可以运行如下所示命令: 使用如下命令编译并测试这个代码: $ arm-linux-gcc -o hello hello.c 五...gcc-g++2.95.3.tar.gz,这个压缩包就是使GCC能够编译C++程序而单独发布。...不知道网友没有想到过这个问题,可能网友知道这些包跟GCC所用包是不相同,仅仅名字不一样而已,但是知道为什么不一样恐怕还是有相当多的人不清楚。

6.5K10

使用Zig在arm64上引导Uber基础设施

我们找到了两种截然不同方法: 在并行区域或现有区域中独立集群提供基本 arm64 支持,并在那里运行测试(实验质量); 让所有的核心基础设施都知道现在不止一种架构,然后像生成其他 SKU 一样生成...既然我们核心基础设施需要提供一流 arm64 支持,那么这个项目就很自然地被分成两个部分: 第一个任务是将包含了我们几乎所有基础架构代码 Go 代码库编译成 arm64 二进制文件; 修改与构建、...例如,一块智能手表可以运行已编译代码,但不能运行编译器,因此我们可以使用交叉编译器手表编译程序。 sysroot 是目标平台文件系统归档。例如,特定于目标平台头文件、共享库、静态库。...Zig 工具链 Zig 采用了不同方式:它对所有受支持目标平台使用了相同工具链。 它在编译时使用了哪些文件?...尽管如此,我们还没有将用 Zig 编写生产应用程序引入到我们代码库中(虽然工具链已经完全设置好了),因为目前公司中只有少数人知道这门语言。

23430

令人沮丧C++性能调试

公平地说,这更像是用词不当——“抽象在经过优化后可能提供零运行时开销”这样说法可能会更恰当一些,但我知道为什么不是这么回事…… 大多数 C++ 程序员倾向于接受这样一个事实——“零成本抽象”只在启用了优化情况下才能提供零运行时开销...&&>(0) 相同,而且大多数人都希望编译器不会为 move 生成代码,即使禁用了优化。...当然,使用 char 并不会生成如此糟糕汇编,即使完全禁用了优化。...另一方面,游戏开发者会嘲笑和避开那些信奉高级抽象和类型安全 C++ 程序员,因为他们没有意识到调试性能和编译速度可能没有更干净、更安全、更可维护代码那么重要。...首先,-Og 只在 GCC 上可用。Clang 接受了这个标志,但它与 -O1 完全相同——LLVM 维护者从未实现过恰当调试优化级别。

93620

一次搞定 Arm Linux 交叉编译

为什么要交叉编译 交叉编译其实是相对于本地编译(native build)来说,我相信大家最开始学习 C/C++ 这些语言时候,都是在电脑上写程序,然后在电脑上编译生成可执行文件,最后在电脑上运行。...程序最后运行环境变了,比如你开发板是基于 Arm ——程序在 X86 上编辑,编译,最终运行在另一个和 X86 完全不同架构 Arm 芯片上。 ?...所以我们要在 X86 电脑上编译出能够在 Arm 上运行程序,我们必须明确告诉编译器,编译生成可执行文件需要以 Arm 指令标准编码。...为了让这个流程变得简单,开发者们不同芯片开发了不同编译器,比如针对 Arm 平台 arm-linux-gcc,针对 mips 平台 mips-linux-gnu-gcc,这些编译器都是基于 GCC...可以用来编译 u-boot、linux kernel 以及应用程序。 另外需要补充一点是,32 位 Arm 和 64 位 Arm,它们指令不同,所以需要使用不同工具链。

26.5K52

CC ++与Rust性能

CC ++编程语言中最接近跳转抽象是goto操作。它不像汇编那样灵活jmp,但是C编译器提供了扩展,使操作员几乎可以完全等同于汇编跳转。...要比较不同语言性能,需要以相同方式在所有语言中实现相同任务。这不是人们通常要做,很难找到不同语言真实代码示例。这些示例将桔子与桔子进行比较,而不是将桔子与苹果进行比较。...[i]; 这些并不是C程序所有低效率,在Rust实施中已将其消除(这两个程序都基于相同初始Ada程序)。...Nginx编写C ++模块很容易,但是我们需要额外粘合代码才能在Rust中开发该模块并维护所有补丁。 NginxC代码相同开发人员可以轻松地在代码CC ++部分之间切换。...问题是,Rust内存安全性(现代核心C ++,静态分析和地址清理器也可以实现)是否使开发如此高效,以至于额外代码和以两种不同语言维护代码库可以忽略不计?

5.3K30

函数调用约定

现代几乎所有的编程语言都离不开函数和参数概念。而这个概念是编程语言级别的,而不是硬件级别的。也就是说硬件上本来没有函数概念。只是函数太普遍,硬件开始函数准备专用指令。...但是这样在使用者来看是不现实完全顺序执行代码在编程初期就被发现不适合开发。于是人们增加了循环,判断,跳转和函数。 函数开始作为几乎所有编程语言基础。...这里命名是指如何编码参数和返回值类型到函数名中。一般编译之后代码函数名都不是代码中编程语言规定函数名。而是根据这个生成。...这些防御能力使得攻击者几乎不能把自己可执行代码放到程序中执行,然而大部分程序运行,几乎都需要外部库。...还有一种方案是使用systemtap,systemtap本身是利用内核kprobe在内核事件中插入中间代码。是完全基于内核机制。 还有一种方案是valgrind采用中间代码

2.2K20

程序C语言快速上手——工程篇(十二)

,例如编译器在编译时候就可以分配内存,那么不同程序会不会分配到相同内存地址,计算机如何处理这种冲突?...即使两个程序操作了一个相同内存地址也不会冲突,因为程序操作都是虚拟地址,操作系统可以根据这两个程序不同进程,分别将两个相同虚拟地址映射到不同物理地址中储存。...有人说,一个C语言代码为什么要经过这么多阶段才能被计算机运行呢? 根本原因是因为CPU只懂二进制指令,其他啥也不懂,你写C语言代码CPU不认识。...生成与位置无关目标文件 使用一下代码生成与位置无关目标文件add.o、sub.o、div.o gcc -fPIC -c add.c sub.c div.c -f后面跟PIC表示生成位置无关代码(...开发、MacOS开发、Linux开发等,唯独WindowsDLL实现原理是完全不同,仅在Windows端适用。

1.3K20

为什么C代码比Python代码运行得更快?

不同之处在于,Python代码不会被CPU立即执行,而是被解释。 就性能而言,这让世界变得不同几乎总是使用虚拟机来运行Python代码 虚拟计算机另一个名称是“字节码解释器”。...尽管如此,虚拟计算机仍会执行创建代码。 原生代码 一旦程序被构建出来,它还没有完全转换为本机代码,直到它被转换为它所设计平台本机二进制CPU指令。...运行时可以提供运行时服务,例如动态对象加载,并构建代码将在其中执行环境。在编译 C 中,存在运行时。已编译C++具有运行时。 为什么 Python 比 C 慢?...你可以提供类型注释以获得与 C 相同速度——如果你选择退出安全检查并承诺某些变量将具有某些类型, 你会得到完全相同机器代码指令(如果你程序有错误,也会得到完全相同奇怪行为)。...结论 在本文中,我们了解了为什么 C 语言代码执行比 Python 更快不同原因。

1.2K30

linux动态库和静态库

二者不同点在于代码被载入时刻不同:    静态库代码在编译过程中已经被载入可执行程序,因此生成可执行程序体积较大。...静态用.a后缀, 例如: libhello.a    共享库(动态库)代码是在可执行程序运行时才载入内存,在编译过程中仅简单引用,因此生成可执行程序代码体积较小。...动态通常用.so后缀, 例如:libhello.so 共享库(动态库)好处是:: 不同应用程序如果调用相同库,那么在内存里只需要有一份该共享库实例。...: 以下面的代码例,生成上面用到hello库: /* hello.c */ #include "hello.h" void sayhello() { printf(..."hello,world "); } 首先用gcc编绎该文件,在编绎时可以使用任何合法编绎参数,例如-g加入调试代码等: gcc -c hello.c -o hello.o 1、生成静态库 生成静态库使用

12.2K20

hello程序是如何被编译出来

前言 hello程序几乎是我们每个人学习C语言写第一个程序,但是它是如何从.c文本变成可以打印出”hello world“可执行文件呢?本文将简单介绍其过程。...想要只生成预处理之后内容,可以使用下面的方式: gcc -E -o helloWorld.i helloWorld.c #-E参数表示只进行预处理 生成helloWorld.i即为预处理之后内容...编译 预处理之后就需要对生成预处理文件进行词法分析,语法分析,语义分析,最终产生汇编代码文件,说白点可以简单理解C代码“翻译”成汇编代码。该过程是核心同时也是较复杂一个过程。...汇编 汇编是将汇编代码翻译成机器可执行指令,生成目标文件。整个过程较为简单,几乎只是按照汇编指令和机器指令进行一一翻译。...而正是由于整个编译过程分阶段进行,我们可以看到不同类型问题在不同阶段出现并且有先后顺序。正因如此,链接问题在编译最后阶段才会出现。

71220

C不再是一种编程语言”

尽管他们各自愤怒原因不尽相同,但本文作者想要表达是:“C 被提升到了一个具备声望和权威角色,它统治是如此地绝对和永恒,以至于它完全扭曲了我们之间对话方式。”...几乎任何程序要做任何有用或有趣事情,它都必须在操作系统上运行。这意味着它必须与那个操作系统交互——而很多操作系统都是用 C 编写。因此,该语言必须与 C 代码交互,这意味着它必须调用 C API。...它可以本地导入 (Objective-)C(++) 头文件,并生成一个漂亮原生 Swift 接口,相关类型会自动“桥接”到 Swift 中对等类型(通常是透明,因为这些类型 ABI 相同)。...让你“codegen”直接生成 C(++),这样用户就需要一个 C 编译器。 基于一个成熟主流 C 编译器(gcc 或 clang)构建自己编译器。...但是,有没有一种方法——如果代码选用了——我们可以在新应用程序中升级函数调用,而让老应用程序保持原样?让我们编写一些代码,测试一下透明别名可以为 ABI 带来什么帮助。

55620

C不再是一种编程语言”

尽管他们各自愤怒原因不尽相同,但本文作者想要表达是:“C 被提升到了一个具备声望和权威角色,它统治是如此地绝对和永恒,以至于它完全扭曲了我们之间对话方式。”...几乎任何程序要做任何有用或有趣事情,它都必须在操作系统上运行。这意味着它必须与那个操作系统交互——而很多操作系统都是用 C 编写。因此,该语言必须与 C 代码交互,这意味着它必须调用 C API。...它可以本地导入 (Objective-)C(++) 头文件,并生成一个漂亮原生 Swift 接口,相关类型会自动“桥接”到 Swift 中对等类型(通常是透明,因为这些类型 ABI 相同)。...让你“codegen”直接生成 C(++),这样用户就需要一个 C 编译器。 基于一个成熟主流 C 编译器(gcc 或 clang)构建自己编译器。...但是,有没有一种方法——如果代码选用了——我们可以在新应用程序中升级函数调用,而让老应用程序保持原样?让我们编写一些代码,测试一下透明别名可以为 ABI 带来什么帮助。

62120

android设备上如何运行C语言原生程序

前言 咱们知道android设备可以直接运行apk应用,或者使用dalvikvm指令运行dex文件中程序, 但是这两者本质上使用语言都是java或者smali, 如果需要执行C语言程序,需要借助NDK...编译成so库, 有没有不使用NDK而直接编译c原生程序然后在安卓设备中运行方式呢?...交叉编译 C语言是一门跨平台语言,语言跨平台,但是程序不跨平台, 也就是说在windows平台下编译程序只能在windows平台上执行,linux亦是如此, 为什么会出现这种情况呢?...除了操作系统导致文件格式不一致之外,本质上是因为不同平台cpu使用架构不一致导致, 目前主流三大cpu架构x86,ARM,MIPS,每个架构都对应着属于自己一套汇编指令, 我们编写程序,最终都会解码成汇编指令被...cpu所指行,那么在windows平台上进行本机编译C语言代码,会根据当前平台cpu架构和操作系统生成只能在当前平台运行程序 如果我想在windows平台编译出能在linux系统或者在ARM 设备中运行程序

4.9K20

关于 Unicode 每个程序员应该知道 5 件事

上周末,曝出了山寨WhatsApp Android应用程序新闻,看似由相同开发者提供作为了官方应用程序。欺诈分子通过在开发者名字中包含unicode非输出空格来避免验证。...与混合可见和不可见字符类似,很少有任何理由允许在标识符中使用混合字符名称,尤其是域名。大多数浏览器已采取措施惩罚混合字符域名,将它们显示十六进制Unicode值,这样用户就不会轻易混淆。...由于有如此相似字符和重叠集合,不同语言或unicode处理库可能会应用不同规范化策略,这会潜在地开放安全风险,如果规范化在几个地方完成的话。...应用程序不同层次对字词进行不同规范化处理——允许用户注册恶意帐户,但是会重置目标帐户密码。...结合拉丁字符(例如U+036B和U+036C)占据上一个字母空格,这样你可以在单个文本行中写入多行文本(’N\u036BO\u036C生成NͫOͬ)。

72120

【Linux】软硬链接与动静态库

当然,假如此时我们将源文件路径给更改,并不会发生什么影响,但是假如我们将源文件给删除。我们会发现,那个数字就会由2变成1,但依然可以运行。 接下来我们看一个现象:为什么目录文件硬链接数2?  ...我们在编写C/C++代码时,实际上一直都在用库(c/c++标准库),在编写代码时,有很多库函数诸如printf等,我们为什么能直接拿来用呢?...动静态库链接原理 为什么静态链接生成可执行程序,不会依赖库文件呢?...因为在编译阶段会将库中方法代码加载到可执行程序中,这样就会出现一个情况,假如同一个方法比如printf,被调用了多次,这也就会导致printf实现代码,被重复复制了多次,出现大量冗余重复代码,这也就是为什么静态链接生成可执行程序体积大小非常大原因...此时动态库地址也就有了。且同一个方法,它库地址+偏移量相同,所以代码只需要存在一份即可,避免了代码冗余。

16930

开篇:预备知识---1

之后在 1989 年 美国国家标准协会(ANSI)发布了第一个 C语言标准,国际标准化组织于 1990 年采用了这套 C 标准(ISO C)。ISO C 和 ANSI C完全相同标准。...C++几乎C ,这意味着任何 C 程序差不多就是一个 C++程序。我们在写 C语言程序时候将源文件后缀名改为 .cpp 就可以在其中使用 C++ 语言特性了。 ​...,因此同一份 html 代码不同厂商浏览器上可能会有不同表现。...当然 CC++ 语言之间语法基本相同,但在某些方面还是有一些区别,我们来看一下这些语法上不同点。...这也是为什么 32 位机器最多只能使用容量 4GB 内存条原因。那么这个机器字长和 C语言有什么关系呢?

48340

【Linux Plumbers 大会总结】Rust 和 GCC 整合两种方式

他开始说,rustc编译器是基于LLVM,除此之外,这意味着它不支持GCC所支持所有体系结构。LLVM有的,rustc也有,但它有一个API,可以插入一个替代代码生成器。...这个API可以用来通过`libgccjit`[4]插入GCC代码生成机制。这就是 rustc_codegen_gcc 所采取方法。 为什么这会是一件有用事情呢?...作为一个实验,这个编译器已经被用来m68k架构构建Rust代码;这项工作仍处于早期阶段,Boucher 说,但它表明确实有可能为LLVM不支持平台构建Rust程序。 仍然有一些问题需要解决。...一些属性仍然需要支持,调试信息生成也是如此生成代码质量并不总是最好。必须做更多工作来支持新体系结构。还不支持链接时优化(LTO),等等。...即便如此,也需要回传这些补丁,以允许使用较早GCC版本,这对于编译内核是很重要。 即便如此,这个项目似乎已经取得了合理进展。

94210

Linux环境使用g++编译C++方法总结

单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单 C++ 程序代码: /* helloworld.cpp */ #include int...gcc 编译过程和输出文件与 g++ 是完全相同。 在大多数系统中,GCC 安装时会安装一名 c++ 程序。...源文件生成对象文件 选项 -c 用来告诉编译器编译源代码但不要执行链接,输出结果对象文件。文件默认名与源码文件名相同,只是将其后缀变为 .o。...例如:除了中间对象文件有不同名字外,下列命令生将生成和上面完全相同可执行文件: $ g++ -c hellospeak.cpp -o hspk1.o $ g++ -c speak.cpp -o...预处理过文件 GCC 后缀 .ii,它可以通过 -o 选项来生成,例如: $ gcc -E helloworld.cpp -o helloworld.ii 生成汇编代码 选项 -S 指示编译器将程序编译成汇编语言

2.8K51

关于 Unicode 每个程序员应该知道 5 件事

之前曝出了山寨WhatsApp Android应用程序新闻,看似由相同开发者提供作为了官方应用程序。欺诈分子通过在开发者名字中包含unicode非输出空格来避免验证。...与混合可见和不可见字符类似,很少有任何理由允许在标识符中使用混合字符名称,尤其是域名。大多数浏览器已采取措施惩罚混合字符域名,将它们显示十六进制Unicode值,这样用户就不会轻易混淆。...由于有如此相似字符和重叠集合,不同语言或unicode处理库可能会应用不同规范化策略,这会潜在地开放安全风险,如果规范化在几个地方完成的话。...应用程序不同层次对字词进行不同规范化处理——允许用户注册恶意帐户,但是会重置目标帐户密码。...结合拉丁字符(例如U+036B和U+036C)占据上一个字母空格,这样你可以在单个文本行中写入多行文本(’NͫOͬ’生成NͫOͬ)。

89870

Linux共享库、静态库、动态库详解

环境变量 各种各样环境变量控制着一些关键过程。例如你可以临时你特定程序一次执行指定一个不同函数库。...坏”,以 了解为什么。...其他类Unix系统处理不同情况,但出于同样原因:setuid / setgid程序不应该受到环境变量不当影响。 3.4。创建共享库 创建共享库很容易。...编译生成对象文件(使用-c),并包含所需-fPIC选项: gcc -fPIC -g -c -Wall ac gcc -fPIC -g -c -Wall bc gcc -shared -Wl,-soname...在几乎所有情况下,您至少有两个依赖关系: /lib/ld-linux.so.N(其中N1或更多,通常至少2)。这是加载所有其他库库。 libc.so.N(N6以上)。这是C库。

8.7K10
领券