所以我刚刚发现 GCC 可以进行内联汇编,我想知道两件事:
能够内联汇编有什么好处?
是否可以使用 GCC 作为汇编编译器/汇编器来学习汇编?
我找到了几篇文章,但它们都是旧的,2000 年和 2001 年,不太确定它们的相关性。
谢谢
所以我刚刚发现 GCC 可以进行内联汇编,我想知道两件事:
能够内联汇编有什么好处?
是否可以使用 GCC 作为汇编编译器/汇编器来学习汇编?
我找到了几篇文章,但它们都是旧的,2000 年和 2001 年,不太确定它们的相关性。
谢谢
内联汇编的好处是有汇编代码,内联(等等,别杀我)。通过这样做,您不必担心调用约定,并且您可以更好地控制最终目标文件(这意味着您可以决定每个变量的位置 - 到哪个寄存器或者它是否存储在内存中),因为该代码赢了' 不被优化(假设您使用 volatile 关键字)。
关于你的第二个问题,是的,有可能。你可以做的是编写简单的 C 程序,然后将它们翻译成汇编,使用
gcc -S source.c
有了这个,以及架构手册(MIPS、Intel 等)以及GCC手册,你可以走很长的路。
网上有一些资料。
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/
内联汇编的缺点是通常您的代码不能在不同的编译器之间移植。
希望能帮助到你。
内联汇编对于就地优化以及访问任何库或操作系统未公开的 CPU 功能非常有用。
例如,某些应用程序需要严格跟踪时序。在 x86 系统上,RDTSC 汇编命令可用于读取内部 CPU 计时器。
使用 GCC 或任何带有内联汇编的 C/C++ 编译器对于小代码片段很有用,但许多环境没有良好的调试支持——这在开发内联汇编提供特定功能的项目时更为重要。此外,如果您使用内联汇编,可移植性将成为一个反复出现的问题。最好在合适的环境(GNU 汇编器、MASM)中创建特定项目并根据需要将它们导入项目。
内联汇编通常用于访问编译器未以其他方式公开的硬件功能(例如,没有提供内在函数的矢量 SIMD 指令),和/或用于手动优化编译器生成次优代码的代码的性能关键部分。
当然,没有什么可以阻止您使用内联汇编器来测试您用汇编语言编写的例程。但是,如果您打算编写大量代码,则最好使用真正的汇编程序,以避免陷入无关紧要的问题。您可能会发现 GNU 汇编器与工具链的其余部分一起安装;)
嵌入自定义汇编代码的好处是有时(我敢说,经常)开发人员可以编写比编译器更有效的汇编代码。因此,对于性能极其密集的项目,自定义编写的程序集可能是有益的。游戏往往会浮现在脑海中......
至于用它来学习汇编,我毫不怀疑你可以。但是,我想使用实际的程序集 SDK 可能是更好的选择。除了学习如何使用该语言的标准实验之外,您可能还需要有关设置开发环境的知识。
您不应该使用内联asm功能来学习汇编语言。
关于它的好处,我同意jldupont,主要是混淆。从理论上讲,它可以让您轻松与编译器集成,因为扩展 asm 的复杂语法允许您在寄存器使用方面与编译器合作,并且可以告诉编译器您希望从内存中加载这个和那个并为你放置在寄存器中,最后,它允许编译器被警告你已经破坏了这个或那个寄存器。
但是,所有这些都可以通过简单地编写符合标准的 C 代码然后编写汇编程序模块并将扩展作为普通函数调用来完成。也许很久以前,过程调用机器操作太慢而无法容忍,但今天你不会注意到。
我相信真正的答案是,一旦您了解了约束 DSL,它就更容易了。人们只需投入一个asm并混淆 C 程序,而不是费心修改 Makefile 并将新模块添加到构建和部署工作流程中。
这不是真正的答案,而是对其他人答案的扩展评论。
内联汇编仍然用于访问 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
但是我不需要这样做,哦,大概十五年了,因为现代编译器要聪明得多。事实上,当前的编译器有时会生成比大多数人更高效的代码。特别是考虑到具有长流水线、分支预测等的 CPU,最快执行的指令序列并不总是对人类最有意义的指令序列。所以你可以说,“按那个顺序做 ABCD”,编译器会打乱这个顺序以提高效率。
对于初学者来说,玩一点内联汇编是很好的,但如果你是认真的,我赞同那些建议你在一段时间后转向“真正的”汇编器的人。
手动优化执行很多的循环。这篇文章很旧,但可以让您了解手动编码程序集的优化类型。
您也可以直接使用 gcc 使用的汇编程序。它被称为as
(参见man as
)。然而,许多关于汇编的书籍和文章都假设您使用的是 DOS 或 Windows 环境。所以在 Linux 上学习可能有点困难(也许在虚拟机上运行 FreeDOS),因为你不仅需要知道你编写代码的处理器(通常可以下载官方手册),还需要知道如何连接到操作系统你在跑步。
Norton 和 Socha 合着的一本使用 DOS 的不错的初学者书籍。它很老了(第三版和最新版是 1992 年的),所以你可以以 0.01 美元的价格买到二手书(不是开玩笑)。我所知道的唯一一本专门针对 Linux 的书是免费的“从头开始编程”