代码之家  ›  专栏  ›  技术社区  ›  Nope

GCC:直列装配-适合吗?

  •  2
  • Nope  · 技术社区  · 16 年前

    所以我刚刚发现GCC可以进行内联组装,我想知道两件事:

    1. 能够内联装配有什么好处?

    2. 是否可以使用gcc作为汇编编译器/汇编程序来学习汇编?

    我找到了几篇文章,但它们都很老套,2000年和2001年,不太确定它们的相关性。

    谢谢

    7 回复  |  直到 16 年前
        1
  •  12
  •   Peter Mortensen Pieter Jan Bonestroo    16 年前

    内联汇编的好处是有内联汇编代码(等等,不要杀我)。通过这样做,您不必担心调用约定,而且您对最终的对象文件有更多的控制(这意味着您可以决定每个变量的位置-哪个寄存器或存储的内存),因为代码不会被优化(假设您使用volatile关键字)。

    关于你的第二个问题,是的,这是可能的。你所能做的就是编写简单的C程序,然后用

    gcc -S source.c
    

    以及体系结构手册( MIPS 以及 GCC 手动,你可以走很远的路。

    网上有一些资料。

    http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

    http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/

    内联程序集的缺点是,通常您的代码在不同的编译器之间是不可移植的。

    希望它有帮助。

        2
  •  9
  •   meklarian    16 年前

    内联程序集对于就地优化和访问任何库或操作系统都不公开的CPU功能非常有用。

    例如,一些应用程序需要严格跟踪时间。在x86系统上,可以使用rdtsc assembly命令读取内部CPU计时器。

    Time Stamp Counter - Wikipedia

    使用GCC或具有内联汇编的任何C/C++编译器对于代码的小片段是有用的,但是许多环境没有良好的调试支持——这将在开发内联程序集提供特定功能的项目时更为重要。此外,如果使用内联程序集,可移植性将成为一个重复出现的问题。最好在适当的环境(GNU汇编程序、MASM)中创建特定的项,并根据需要导入它们。

        3
  •  8
  •   moonshadow    16 年前

    内联汇编通常用于访问编译器未公开的硬件功能(例如,没有提供内部函数的矢量SIMD指令),和/或手动优化编译器生成次优代码的性能关键代码部分。

    当然,没有什么可以阻止您使用内联汇编程序来测试用汇编语言编写的例程;但是,如果您打算编写大量代码,最好使用真正的汇编程序来避免陷入无关的困境。您可能会发现GNU汇编程序与其他工具链一起安装;)

        4
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    16 年前
    1. 嵌入自定义程序集代码的好处是开发人员有时(我敢说,经常)可以比编译器更高效地编写程序集代码。因此,对于性能非常密集的项目,自定义编写的程序集可能是有益的。游戏往往会浮现在脑海中……

    2. 至于用它来学习装配,我毫不怀疑你能做到。但是,我认为使用实际的汇编SDK可能是更好的选择。除了学习如何使用语言的标准实验之外,您可能还需要关于建立开发环境的知识。

        5
  •  2
  •   Community Mohan Dere    9 年前

    您不应该通过使用内联来学习汇编语言 ASM 特征。

    关于它的好处,我同意 jldupont 主要是混淆。理论上,它允许您轻松地与编译器集成,因为扩展asm的复杂语法允许您在寄存器的使用上与编译器合作,并且它允许您告诉编译器您希望从内存中加载这个和那个,并将其放入寄存器中,最后,它允许编译器被警告你把这本书或那本书都删掉了。

    然而,所有这些都可以通过简单地编写符合标准的C代码,然后编写汇编程序模块,并将扩展作为一个正常的函数调用来完成。也许很久以前,程序调用机器操作太慢,无法容忍,但今天您不会注意到。

    我相信真正的答案是,一旦你了解了反DSL,它就更容易了。人们只是把 ASM 并混淆C程序,而不是麻烦修改makefile并向构建和部署工作流添加新模块。

        6
  •  2
  •   Bob Murphy    16 年前

    这不是一个真正的答案,而是对其他人答案的一种扩展评论。

    内联程序集仍用于访问CPU功能。例如,在手机中使用的ARM芯片中,不同的制造商通过特殊的功能来区分他们的产品,这些特殊的机器语言指令在C/C++中是不等价的。

    回到80年代和90年代早期,我经常使用内联装配来优化循环。例如,当时针对680x0处理器的C编译器会做一些非常愚蠢的事情,比如:

    calculate a value and put it in data register D1
    PUSH D1, A7     # Put the value from D1 onto the stack in RAM
    POP D1, A7      # Pop it back off again
    do something else with the value in D1
    

    但我在,哦,可能是15年内没必要这么做,因为现代编译器要聪明得多。事实上,当前的编译器有时会生成比大多数人更高效的代码。特别是对于具有长管道、分支预测等的CPU,执行最快的指令序列并不总是对人类最有意义的指令序列。所以你可以说,“按这个顺序做一个B-C-D”,编译器会为了更高的效率而到处乱序。

    对初学者来说,稍微使用内联汇编是不错的,但是如果你是认真的,我会附和那些建议你在一段时间后转向“真正的”汇编程序的人。

        7
  •  1
  •   mdm    16 年前
    1. 手动优化大量执行的循环。 This 这篇文章很旧,但是可以给您一个关于手工编码程序集的优化类型的概念。

    2. 还可以直接使用gcc使用的汇编程序。它叫 as (见 man as )然而,许多关于汇编的书籍和文章都假定您使用的是DOS或Windows环境。因此,在Linux上学习可能有点困难(可能在虚拟机上运行freedos),因为您不仅需要了解为其编写代码的处理器(通常可以下载官方手册),还需要了解如何连接到正在运行的操作系统。

    诺顿和索契的书是一本使用DOS的入门书。它很旧(第三版和最新版本是1992年的),所以你可以花0.01美元(不是开玩笑)买到二手书。我所知道的唯一一本专门针对Linux的书是免费的。” Programming from the Ground Up

    推荐文章