你为什么要使用汇编语言进行编程?

89

我有一个问题想问所有热衷于低级黑客技术的人。我在一篇博客中看到了这句话。我认为源并不重要(如果你真的在意,它是Haack),因为这似乎是一个常见的说法。

例如,许多现代三维游戏都使用C++和汇编语言编写其高性能核心引擎。

至于汇编代码-是因为您不希望编译器发出额外的指令或使用过多的字节,还是因为您在使用更好的算法,这些算法无法用C语言表达(或无法表达而不被编译器干扰)?

我完全理解了解低级别的东西的重要性。我只是想了解为什么在了解了它之后要在汇编中编程。


1
已经有类似的问题了,我想... - Mehrdad Afshari
8
嗯,严格来说这是一个不同的问题。那些问题都是关于为什么要学习汇编语言,而这个问题是为什么要用它来编程,我认为这是不同的……? - cgp
4
你为什么使用汇编语言进行编程?--让我们来看一些不可能的答案:1)为了使我的代码可维护,2)灵活性,3)确保可移植性,4)可测试性,5)可读性... - ivan_ivanovich_ivanoff
9
工作保障 - San Jacinto
3
因为这很有趣.. :) - RainingComputers
显示剩余4条评论
30个回答

5

缺陷往往以每行(语句、代码点等)为单位;尽管对于大多数问题来说,汇编语言会比高级语言使用更多的行,但有时候它是最佳的(最简洁、最少的行)解决方案。这些情况大多涉及到常见的情况,例如驱动程序和嵌入式系统中的位掩码。


3

如果你参与了所有的Y2K修复工作,如果你懂汇编语言,你可以赚很多钱。现在还有很多遗留代码是用汇编语言编写的,这些代码偶尔需要维护。


3

另一个原因可能是当现有的编译器对于某个架构来说并不够好,并且程序中所需的代码量并不长或复杂,以至于程序员不会迷失在其中。尝试为嵌入式系统编程微控制器,通常汇编语言会更容易。


3
除了其他提到的事情外,所有高级语言都有一定的限制。这就是为什么有些人选择使用汇编语言编程,以便对其代码具有完全控制权。
其他人则喜欢非常小的可执行文件,例如在20-60KB范围内检查 HiEditor,它由HiEdit控件的作者实现,是Windows上功能强大的编辑控件,具有语法突出显示和标签,仅约50kb。在我的收藏中,我有超过20个这样的黄金控件,从类似于电子表格的Excell到HTML呈现器。

3

我认为很多游戏开发者会对这个信息感到惊讶。

我所知道的大多数游戏尽可能地少使用汇编语言。在某些情况下根本不使用,最坏的情况下只有一两个循环或函数。

这个引用过于概括了,并不像十年前那么真实。

但是,嘿,事实并不应该阻碍真正黑客的汇编语言之旅。 ;)


3

如果你正在编程一款只有128字节RAM和4K程序存储器的低端8位微控制器,你几乎没有选择只能使用汇编语言。然而,当你需要在更强大的微控制器上执行某个确切时间的动作时,汇编语言就非常有用了,因为你可以计算指令的数量并测量代码使用的时钟周期。


3
游戏对性能要求很高,尽管现在优化器已经相当不错了,但“大师级程序员”仍然可以通过手工编写适当的汇编代码来挤出更多的性能。
绝不要在未进行性能分析之前开始优化程序。在进行性能分析后,应该能够确定瓶颈所在,如果找到更好的算法等方法不能解决问题,可以尝试手工编写一些汇编代码。

2
很多人喜欢贬低汇编语言,因为他们从未学过它的编码方式,只是模糊地接触过它,这让他们感到惊讶或有些受到威胁。真正有才华的程序员会明白,抨击C或汇编是没有意义的,因为它们是互补的。事实上,其中一个的优势就是另一个的劣势。 C的有组织的语法规则提高了代码的清晰度,但同时放弃了汇编因没有任何结构规则而具有的所有优势! C代码指令旨在创建非阻塞代码,可以认为这迫使编程意图更加清晰,但这是一种力量的损失。在C中,编译器不允许在if / elseif / else / end内跳转。或者您不能写两个for / end循环,这些循环在不同变量之间重叠,您不能编写自修改代码(或不能以无缝易用的方式),等等。传统程序员对此感到恐慌,并且根本不知道如何使用这些方法的力量,因为他们被教育遵循传统规则。 这是事实:今天我们拥有计算能力更强的机器,可以完成比我们使用它们进行的应用程序更多的任务,但人类大脑无法在无规则编码环境(=汇编)中编写它们,并需要大大减少谱系和简化编码的限制性规则。 我自己编写过代码,如果不考虑上述限制,则无法使用C代码编写,因为效率会大幅降低。我还没有谈论速度,大多数人认为这是编写汇编的主要原因,如果您的思维局限于C,则永远是编译器的奴隶。我一直认为,国际象棋高手将是理想的汇编程序员,而C程序员只是玩“跳棋”。

2
自修改代码在大多数现代CPU上并不有用,除了JIT-once/run-many场景之外。但是将常量填充为立即数是一种有趣的可能性。C语言中的goto允许在函数内进行非结构化跳转,包括在同一函数中的if()或循环块中。例如:https://godbolt.org/z/IINHTg。还可以使用Duff's Device,将switch/case用于do{}while()循环,以表达跳转到未展开的循环中。但是,如果你降到这个混乱的层次,编写汇编代码可能会更清晰明了。 - Peter Cordes
2
当然,Duff的设备只在具有后增地址的机器上有用,否则未展开循环内部的入口点将破坏优化的大部分目的。 - Peter Cordes

2
上次我写汇编语言是因为我无法说服编译器生成不依赖于libc的位置无关代码。
下一次可能会出于同样的原因。
当然,我以前也有其他原因

2
除了在非常小的CPU上进行非常小的项目之外,我不会打算用汇编语言编写整个项目。然而,通常情况下,一些内部循环的手动编码可以缓解性能瓶颈。
在某些情况下,真正需要的只是用优化器无法找到如何使用的指令替换某些语言结构。一个典型的例子是在DSP应用程序中,向量操作和乘加操作对于优化器来说很难发现,但是手动编码很容易。
例如,某些型号的SH4包含4x4矩阵和4个向量指令。通过将等效的C操作替换为适当的指令,在微小的代价下将校正矩阵扩大到4x4以匹配硬件假设,我看到了色彩校正算法的巨大性能提升。这是通过编写不超过十几行汇编代码,并在周围的少数几个位置进行相关数据类型和存储的匹配调整来实现的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接