C语言 为什么不经常用汇编编写程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2684364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why aren't programs written in Assembly more often?
提问by mudge
It seems to be a mainstream opinion that assembly programming takes longer and is more difficult to program in than a higher level language such as C. Therefore it seems to be recommend or assumed that it is better to write in a higher level language for these reasons and for the reason of better portability.
似乎主流观点认为汇编编程比 C 等高级语言需要更长的时间并且更难编程。因此,由于这些原因,似乎建议或假设使用高级语言编写更好并且为了更好的便携性。
Recently I've been writing in x86 assembly and it has dawned on me that perhaps these reasons are not really true, except perhaps portability. Perhaps it is more of a matter of familiarity and knowing how to write assembly well. I also noticed that programming in assembly is quite different than programming in an HLL. Perhaps a good and experienced assembly programmer could write programs just as easily and as quickly as an experienced C programmer writing in C.
最近我一直在用 x86 汇编编写代码,我突然意识到这些原因可能不是真的,除了可移植性。也许更多的是熟悉和知道如何写好汇编。我还注意到汇编编程与 HLL 编程完全不同。也许一个优秀且经验丰富的汇编程序员可以像用 C 语言编写的有经验的 C 程序员一样轻松快速地编写程序。
Perhaps it is because assembly programming is quite different than HLLs, and so requires different thinking, methods and ways, which makes it seem very awkward to program in for the unfamiliar, and so gives it its bad name for writing programs in.
可能是因为汇编编程和 HLL 有很大的不同,所以需要不同的思维、方法和方式,这使得不熟悉的人编程看起来很尴尬,因此给它写程序的坏名声。
If portability isn't an issue, then really, what would C have over a good assembler such as NASM?
如果可移植性不是问题,那么实际上,与 NASM 之类的优秀汇编器相比,C 有什么优势?
Edit:Just to point out. When you are writing in assembly, you don't have to write just in instruction codes. You can use macros and procedures and your own conventions to make various abstractions to make programs more modular, more maintainable and easier to read. This is where being familiar with how to write good assembly comes in.
编辑:只是指出。当您使用汇编语言编写时,您不必只编写指令代码。您可以使用宏和过程以及您自己的约定来进行各种抽象,以使程序更模块化、更易于维护和更易于阅读。这就是熟悉如何编写好的程序集的用武之地。
回答by Sedat Kapanoglu
Hellо, I am a compiler.
你好,我是一个编译器。
I just scanned thousands of lines of code while you were reading this sentence. I browsed through millions of possibilities of optimizing a single line of yours using hundreds of different optimization techniques based on a vast amount of academic research that you would spend years getting at. I won't feel any embarrassment, not even a slight ick, when I convert a three-line loop to thousands of instructions just to make it faster. I have no shame to go to great lengths of optimization or to do the dirtiest tricks. And if you don't want me to, maybe for a day or two, I'll behave and do it the way you like. I can transform the methods I'm using whenever you want, without even changing a single line of your code. I can even show you how your code would look in assembly, on different processor architectures and different operating systems and in different assembly conventions if you'd like. Yes, all in seconds. Because, you know, I can; and you know, you can't.
当你阅读这句话时,我刚刚扫描了数千行代码。我浏览了数以百万计的可能性,使用数百种不同的优化技术优化你的一行,基于大量的学术研究,你会花费数年的时间。当我将三行循环转换为数千条指令只是为了使其更快时,我不会感到任何尴尬,甚至不会感到轻微的不适。我毫不羞耻地进行大量优化或做最肮脏的把戏。如果你不想让我这样做,也许一两天,我会按照你喜欢的方式行事。我可以随时转换我正在使用的方法,甚至无需更改一行代码。我什至可以向你展示你的代码在汇编中的样子,如果您愿意,可以在不同的处理器架构和不同的操作系统以及不同的汇编约定中使用。是的,一切都在几秒钟内。因为,你知道,我可以;你知道,你不能。
P.S. Oh, by the way you weren't using half of the code you wrote. I did you a favor and threw it away.
PS哦,顺便说一下,您没有使用您编写的一半代码。我帮了你一个忙把它扔掉了。
回答by Ben S
ASM has poor legibilityand isn't really maintainablecompared to higher-level languages.
与高级语言相比,ASM 的易读性很差,并且无法真正维护。
Also, there are many fewer ASM developersthan for other more popular languages, such as C.
此外,与其他更流行的语言(例如 C)相比,ASM 开发人员要少得多。
Furthermore, if you use a higher-level language and new ASM instructions become available(SSE for example), you just need to update your compiler and your old code can easily make use of the new instructions.
此外,如果您使用高级语言并且新的 ASM 指令可用(例如 SSE),您只需要更新您的编译器,您的旧代码就可以轻松使用新指令。
What if the next CPU has twice as many registers?
如果下一个 CPU 的寄存器数量是原来的两倍怎么办?
The converse of this question would be: What functionality do compilers provide?
这个问题的反面是:编译器提供什么功能?
I doubt you can/want to/should optimize your ASM better than gcc -O3can.
我怀疑您是否可以/想要/应该更好地优化 ASM gcc -O3。
回答by mudge
I've written shedloads of assembler for the 6502, Z80, 6809 and 8086 chips. I stopped doing so as soon as C compilers became available for the platforms I was addressing, and immediately became at least 10x more productive. Most good programmers use the tools they use for rational reasons.
我已经为 6502、Z80、6809 和 8086 芯片编写了大量汇编程序。一旦 C 编译器可用于我正在处理的平台,我就停止这样做,并且立即变得至少 10 倍的生产力。大多数优秀的程序员出于合理的原因使用他们使用的工具。
回答by egrunin
I love programming in assembly language, but it takes more code to do the same thing as in a high-level languge, and there is a direct correlation between lines of code and bugs. (This was explained decades ago in The Mythical Man-Month.)
我喜欢用汇编语言编程,但要完成与高级语言相同的事情需要更多的代码,而且代码行和错误之间存在直接关联。(这在几十年前的神话人月中得到了解释。)
It's possible to think of C as 'high level assembly', but get a few steps above that and you're in a different world. In C# you don't think twice about writing this:
可以将 C 视为“高级汇编”,但如果再往上走几步,您就会进入一个不同的世界。在 C# 中,你不会三思而后行:
foreach (string s in listOfStrings) { /* do stuff */ }
This would be dozens, maybe hundreds of lines of code in assembly, each programmer implementing it would take a different approach, and the next person coming along would have to figure it out. So if you believe (as many do) that programs are written primarily for other people to read, assembly is less readable than the typical HLL.
这将是几十行,也许是数百行汇编代码,每个实现它的程序员将采用不同的方法,下一个人必须弄清楚。因此,如果您相信(和许多人一样)程序主要是为其他人阅读而编写的,那么汇编的可读性不如典型的 HLL。
Edit:I accumulated a personal library of code used for common tasks, and macros for implementing C-like control structures. But I hit the wall in the 90s, when GUIs became the norm. Too much time was being spent on things that were routine.
编辑:我积累了一个用于常见任务的个人代码库,以及用于实现类 C 控制结构的宏。但我在 90 年代碰壁了,当时 GUI 成为常态。太多的时间花在了常规的事情上。
The last task I had where ASM was essential was a few years ago, writing code to combat malware. No user interface, so it was all the fun parts without the bloat.
我在 ASM 必不可少的最后一项任务是几年前,编写代码来对抗恶意软件。没有用户界面,所以它是所有有趣的部分,没有膨胀。
回答by Brian Postow
In addition to other people's answers of readability, maintainability, shorter code and therefore fewer bugs, and being much easier, I'll add an additional reason:
除了其他人对可读性、可维护性、更短的代码和更少的错误以及更容易的回答之外,我还要添加一个额外的原因:
program speed.
程序速度。
Yes, in assembly you can hand tune your code to make use of every last cycle and make it as fast as is physically possible. However who has the time? If you write a not-completely-stupid C program, the compiler will do a really good job of optimizing for you. Probably making at least 95% of the optimizations you'd do by hand, without you having to worry about keeping track of any of it. There's definitely a 90/10 kind of rule here, where that last 5% of optimizations will end up taking up 95% of your time. So why bother?
是的,在汇编中,您可以手动调整代码以利用每个最后一个周期并使其尽可能快。然而谁有时间呢?如果你编写一个不完全愚蠢的 C 程序,编译器会为你做一个非常好的优化工作。可能至少 95% 的优化是您手动完成的,而您不必担心跟踪任何优化。这里肯定有 90/10 的规则,最后 5% 的优化最终会占用您 95% 的时间。那么何必呢?
回答by Blindy
If an average production program has say 100k lines of code, and each line is about 8-12 assembler instructions, that would be 1 million of assembler instructions.
如果一个普通的生产程序有 10 万行代码,每行大约有 8-12 条汇编指令,那就是 100 万条汇编指令。
Even if you could write all this by hand at a decent speed (remember, its 8 times more code that you have to write), what happens if you want to change some of the functionality? Understanding something you wrote a few weeks ago out of those 1 million instructions is a nightmare! There's no modules, no classes, no object-oriented design, no frameworks, no nothing. And the amount of similar looking code you have to write for even the simplest things is daunting at best.
即使您可以以不错的速度手动编写所有这些(请记住,您必须编写的代码是其 8 倍),如果您想更改某些功能会怎样?从这 100 万条指令中理解你几周前写的东西是一场噩梦!没有模块,没有类,没有面向对象的设计,没有框架,什么都没有。而且,即使是最简单的事情,您也必须编写大量相似的代码,充其量也是令人生畏的。
Besides, you can't optimize your code nearly as well as a high level language. Where C for example performs an insane number of optimizations because you describeyour intent, not only your code, in assembler you only write code, the assembler can't really perform any note-worthy optimizations on your code. What you write is what you get, and trust me, you can't reliably optimize 1 million instructions that you patch and patch as you write it.
此外,您几乎无法像高级语言一样优化代码。例如,C 执行大量优化,因为您描述了您的意图,而不仅仅是您的代码,在汇编程序中您只编写代码,汇编程序无法真正对您的代码执行任何值得注意的优化。你写的就是你得到的,相信我,你不能可靠地优化你在编写时修补和修补的 100 万条指令。
回答by Maurice Perry
Well I have been writing a lot of assembly "in the old days", and I can assure you that I am much more productive when I write programs in a high level language.
好吧,“过去”我一直在写很多汇编,我可以向你保证,当我用高级语言编写程序时,我的工作效率会更高。
回答by Dale Hagglund
A reasonable level of assembler competence is a useful skill, especially if you work at any sort of system level or embedded programming, not so much because you have to write that much assembler, but because sometimes it's important to understand what the box is reallydoing. If you don't have a low-level understanding of assembler concepts and issues, this can be very difficult.
合理水平的汇编能力是一项有用的技能,特别是如果您从事任何类型的系统级别或嵌入式编程工作,并不是因为您必须编写那么多汇编程序,而是因为有时了解盒子真正在做什么很重要. 如果您对汇编程序的概念和问题没有低级理解,这可能会非常困难。
However, as for actually writing much code in assembler, there are several reasons it's not much done.
然而,至于在汇编程序中实际编写大量代码,有几个原因没有完成。
There's simply no (almost) need. Except for something like the very early system initialization and perhaps a few assembler fragments hidden in C functions or macros, all very low-level code that might once have been written in assembler can be written in C or C++ with no difficulty.
Code in higher-level languages (even C and C++) condenses functionality into far fewer lines, and there is considerable research showing that the number of bugs correlates with the number of lines of source code. Ie, the same problem, solved in assembler and C, will have more bugs in assembler simply because its longer. The same argument motivates the move to higher level languages such as Perl, Python, etc.
Writing in assembler, you have to deal with every single aspect of the problem, from detailed memory layout, instruction selection, algorithm choices, stack management, etc. Higher level languages take all this away from you, which is why are so much denser in terms of LOC.
根本没有(几乎)需要。除了像非常早期的系统初始化和可能隐藏在 C 函数或宏中的一些汇编程序片段之外,所有可能曾经用汇编程序编写的非常低级的代码都可以毫无困难地用 C 或 C++ 编写。
高级语言(甚至 C 和 C++)中的代码将功能压缩到更少的行中,并且有大量研究表明错误的数量与源代码的行数相关。即,同样的问题,在汇编程序和 C 中解决,在汇编程序中将有更多的错误,因为它更长。同样的论点促使人们转向更高级的语言,如 Perl、Python 等。
用汇编程序编写,你必须处理问题的每一个方面,从详细的内存布局、指令选择、算法选择、堆栈管理等。高级语言把这一切都带走了,这就是为什么在LOC 条款。
Essentially, all of the above are related to the level of abstraction available to you in assembler versus C or some other language. Assembler forces you to make all of your own abstractions, and to maintain them through your own self-discipline, where any mid-level language like C, and especially higher level languages, provide you with abstractions out of the box, as well as the ability to create new ones relatively easily.
本质上,以上所有内容都与您在汇编程序与 C 或其他语言中可用的抽象级别有关。Assembler 迫使你自己做所有的抽象,并通过你自己的自律来维护它们,任何像 C 这样的中级语言,尤其是高级语言,都为你提供开箱即用的抽象,以及能够相对容易地创建新的。
回答by Steve Jessop
When you are writing in assembly, you don't have to write just in instruction codes. You can use macros and procedures and your own conventions to make various abstractions to make programs more modular, more maintainable and easier to read.
当您使用汇编语言编写时,您不必只编写指令代码。您可以使用宏和过程以及您自己的约定来进行各种抽象,以使程序更模块化、更易于维护和更易于阅读。
So what you're basically saying is, that with skilled use of a sophisticated assembler, you can make your ASM code closer and closer to C (or anyway another low-ish-level language of your own invention), until eventually you are just as productive as a C programmer.
所以你基本上是说,通过熟练使用复杂的汇编程序,你可以让你的 ASM 代码越来越接近 C(或者你自己发明的另一种低级语言),直到最终你只是和 C 程序员一样高效。
Does that answer your question? ;-)
这是否回答你的问题?;-)
I don't say this idly: I have programmed using exactly such an assembler and system. Even better, the assembler could target a virtual processor, and a separate translator compiled the output of the assembler for a target platform. Much as happens with LLVM's IF, but in its early forms pre-dating it by about 10 years. So there was portability, plus the ability to write routines for a specific target asssembler where required for efficiency.
我不是随便说的:我已经使用这样的汇编程序和系统进行了编程。更好的是,汇编器可以针对虚拟处理器,而单独的翻译器为目标平台编译汇编器的输出。与 LLVM 的 IF 发生的情况非常相似,但其早期形式比它早了大约 10 年。因此具有可移植性,以及在需要效率的情况下为特定目标汇编程序编写例程的能力。
Writing using that assembler was about as productive as C, and with by comparison with GCC-3 (which was around by the time I was involved) the assembler/translator produced code that was roughly as fast and usually smaller. Size was really important, and the company had few programmers and was willing to teach new hires a new language before they could do anything useful. And we had the back-up that people who didn't know the assembler (e.g. customers) could write C and compile it for the same virtual processor, using the same calling convention and so on, so that it interfaced neatly. So it felt like a marginal win.
使用该汇编器编写代码的效率与 C 差不多,并且与 GCC-3(在我参与的时候差不多)相比,汇编器/翻译器生成的代码大致一样快,而且通常更小。规模真的很重要,公司几乎没有程序员,而且愿意在新员工做任何有用的事情之前教他们一门新语言。而且我们有备份,不知道汇编程序的人(例如客户)可以编写 C 并为同一个虚拟处理器编译它,使用相同的调用约定等等,这样它就可以整齐地接口。所以这感觉就像是微不足道的胜利。
That was with multiple man-years of work in the bag developing the assembler technology, libraries, and so on. Admittedly much of which went into making it portable, if it had only ever been targeting one architecture then the all-singing all-dancing assembler would have been much easier.
那是在开发汇编器技术、库等方面花费了多年的工作。不可否认,其中大部分都用于使其可移植,如果它只针对一种架构,那么全能全能汇编器会容易得多。
In summary: you may not like C, but it doesn't mean that the effort of using C is greater than the effort of coming up with something better.
总结:您可能不喜欢 C,但这并不意味着使用 C 的努力大于提出更好的东西的努力。
回答by bta
As a developer who spends most of his time in the embedded programming world, I would argue that assembly is far from a dead/obsolete language. There is a certain close-to-the-metal level of coding (for example, in drivers) that sometimes cannot be expressed as accurately or efficiently in a higher-level language. We write nearly all of our hardware interface routines in assembler.
作为一名大部分时间都花在嵌入式编程领域的开发人员,我认为汇编远非一种死/过时的语言。有某种接近金属的编码水平(例如,在驱动程序中)有时无法用高级语言准确或有效地表达。我们几乎所有的硬件接口程序都是用汇编程序编写的。
That being said, this assembly code is wrapped such that it can be called from C code and is treated like a library. We don't write the entire program in assembly for many reasons. First and foremost is portability; our code base is used on several products that use different architectures and we want to maximize the amount of code that can be shared between them. Second is developer familiarity. Simply put, schools don't teach assembly like they used to, and our developers are far more productive in C than in assembly. Also, we have a wide variety of "extras" (things like libraries, debuggers, static analysis tools, etc) available for our C code that aren't available for assembly language code. Even if we wanted to write a pure-assembly program, we would not be able to because several critical hardware libraries are only available as C libs. In one sense, it's a chicken/egg problem. People are driven away from assembly because there aren't as many libraries and development/debug tools available for it, but the libs/tools don't exist because not enough people use assembly to warrant the effort creating them.
话虽如此,这个汇编代码被包装成可以从 C 代码中调用,并被视为一个库。出于多种原因,我们不会用汇编语言编写整个程序。首先是便携性;我们的代码库用于使用不同架构的多种产品,我们希望最大限度地增加可以在它们之间共享的代码量。其次是开发人员的熟悉程度。简而言之,学校不像过去那样教汇编,我们的开发人员在 C 方面的工作效率远高于汇编。此外,我们有各种各样的“附加功能”(如库、调试器、静态分析工具等)可用于我们的 C 代码,而这些“附加功能”不适用于汇编语言代码。即使我们想写一个纯汇编程序,我们无法做到,因为几个关键硬件库只能作为 C 库使用。从某种意义上说,这是一个鸡/蛋问题。人们远离汇编是因为没有那么多可用的库和开发/调试工具,但库/工具不存在,因为没有足够的人使用汇编来保证创建它们的努力。
In the end, there is a time and a place for just about any language. People use what they are most familiar and productive with. There will probably always be a place in a programmer's reperttheitroade for assembly, but most programmers will find that they can write code in a higher-level language that is almost as efficient in far less time.
最后,几乎任何语言都有一个时间和地点。人们使用他们最熟悉和最有效率的东西。程序员的汇编语言中可能总会有一席之地,但大多数程序员会发现他们可以用更高效的高级语言编写代码,而且时间要短得多。

