了解汇编程序的原因之一是,有时可以使用汇编程序来编写比用高级语言(特别是C语言)编写的代码性能更好的代码。然而,我也听人说过很多次,尽管这并非完全错误,但实际上可以使用汇编程序来生成性能更好的代码的情况极其罕见,并且需要汇编方面的专业知识和经验。

这个问题甚至没有涉及到这样一个事实,即汇编程序指令将是特定于机器的、不可移植的,或者汇编程序的任何其他方面。当然,除了这一点之外,了解汇编还有很多很好的理由,但这是一个需要示例和数据的具体问题,而不是关于汇编程序与高级语言的扩展论述。

谁能提供一些具体的例子,说明使用现代编译器汇编代码比编写良好的C代码更快,并且您能否用分析证据支持这一说法?我相信这些案例确实存在,但我真的很想知道这些案例到底有多深奥,因为这似乎是一个有争议的问题。


当前回答

如果您没有查看编译器生成的内容的反汇编,您实际上无法知道编写良好的C代码是否真的很快。很多时候你会发现“写得好”是主观的。

因此,没有必要用汇编程序来获得最快的代码,但出于同样的原因,了解汇编程序当然是值得的。

其他回答

在处理器速度以MHz为单位,屏幕尺寸低于100万像素的时代,一个众所周知的更快显示的技巧是展开循环:为屏幕的每个扫描行写操作。它避免了维护循环索引的开销!再加上检测屏幕刷新,它非常有效。 这是C编译器不会做的事情……(虽然通常可以在速度优化和规模优化之间进行选择,但我认为前者使用了一些类似的技巧。)

我知道有些人喜欢用汇编语言编写Windows应用程序。他们声称他们更快(很难证明)和更小(确实如此!)。 显然,虽然这样做很有趣,但可能会浪费时间(当然,学习目的除外!),特别是对于GUI操作…… 现在,也许某些操作(比如在文件中搜索字符串)可以通过精心编写的汇编代码进行优化。

我很惊讶居然没人这么说。如果用汇编编写strlen()函数,速度会快得多!在C中,你能做的最好的事情就是

int c;
for(c = 0; str[c] != '\0'; c++) {}

在组装过程中,你可以大大加快速度:

mov esi, offset string
mov edi, esi
xor ecx, ecx

lp:
mov ax, byte ptr [esi]
cmp al, cl
je  end_1
cmp ah, cl
je end_2
mov bx, byte ptr [esi + 2]
cmp bl, cl
je end_3
cmp bh, cl
je end_4
add esi, 4
jmp lp

end_4:
inc esi

end_3:
inc esi

end_2:
inc esi

end_1:
inc esi

mov ecx, esi
sub ecx, edi

长度单位是ecx。这一次比较4个字符,所以速度快4倍。并且考虑使用eax和ebx的高阶词,它将比之前的C例程快8倍!

简短的回答吗?有时。

从技术上讲,每一个抽象都有成本,而编程语言是CPU如何工作的抽象。然而C非常接近。几年前,我记得当我登录UNIX帐户并收到以下财富信息时(当时这种东西很流行),我笑出声来:

C程序设计语言——A 语言结合了 汇编语言的灵活性 汇编语言的强大。

这很有趣,因为这是真的:C就像可移植的汇编语言。

值得注意的是,汇编语言无论如何编写都可以运行。然而,在C语言和它生成的汇编语言之间有一个编译器,这是非常重要的,因为你的C代码有多快与你的编译器有多好有很大关系。

当gcc出现时,它如此受欢迎的原因之一是它通常比许多商业UNIX版本附带的C编译器要好得多。它不仅是ANSI C(没有任何K&R C的垃圾),更健壮,通常能产生更好(更快)的代码。不是总是,而是经常。

我告诉你这一切是因为没有关于C和汇编器速度的统一规则,因为C没有客观的标准。

同样地,汇编程序也会根据你正在运行的处理器、你的系统规格、你正在使用的指令集等而有很大的不同。历史上有两个CPU体系结构家族:CISC和RISC。CISC中最大的玩家过去是,现在仍然是Intel x86架构(和指令集)。RISC主宰了UNIX世界(MIPS6000、Alpha、Sparc等等)。CISC赢得了民心之战。

不管怎样,当我还是一个年轻的开发人员时,流行的观点是,手写的x86通常比C快得多,因为架构的工作方式,它的复杂性受益于人类的操作。另一方面,RISC似乎是为编译器设计的,所以没有人(我知道)写Sparc汇编器。我相信这样的人确实存在,但毫无疑问,他们现在都疯了,被送进了精神病院。

指令集是一个重要的点,即使在同一家族的处理器。某些英特尔处理器具有SSE到SSE4等扩展。AMD有他们自己的SIMD指令。像C这样的编程语言的好处是,人们可以编写他们的库,以便对您运行的任何处理器进行优化。这在汇编程序中是一项艰苦的工作。

你仍然可以在汇编程序中做一些编译器无法做的优化,一个编写良好的汇编程序算法将会和它的C等效程序一样快或更快。更大的问题是:这样做值得吗?

Ultimately though assembler was a product of its time and was more popular at a time when CPU cycles were expensive. Nowadays a CPU that costs $5-10 to manufacture (Intel Atom) can do pretty much anything anyone could want. The only real reason to write assembler these days is for low level things like some parts of an operating system (even so the vast majority of the Linux kernel is written in C), device drivers, possibly embedded devices (although C tends to dominate there too) and so on. Or just for kicks (which is somewhat masochistic).

The question is a bit misleading. The answer is there in your post itself. It is always possible to write assembly solution for a particular problem which executes faster than any generated by a compiler. The thing is you need to be an expert in assembly to overcome the limitations of a compiler. An experienced assembly programmer can write programs in any HLL which performs faster than one written by an inexperienced. The truth is you can always write assembly programs executing faster than one generated by a compiler.

如果您没有查看编译器生成的内容的反汇编,您实际上无法知道编写良好的C代码是否真的很快。很多时候你会发现“写得好”是主观的。

因此,没有必要用汇编程序来获得最快的代码,但出于同样的原因,了解汇编程序当然是值得的。