为什么程序不是更经常用Assembly编写的?[关闭]


216

主流的观点似乎是:汇编语言比诸如C的高级语言花费的时间更长,并且编程起来更困难。因此,出于这些原因,似乎建议或假定最好使用高级语言编写并且出于更好的可移植性。

最近,我一直在写x86汇编语言,这使我意识到,也许这些原因并不是真的,除了可移植性。也许更多的是熟悉和知道如何编写汇编。我还注意到,汇编语言编程与HLL编程完全不同。也许一个优秀且经验丰富的汇编程序员可以像使用C语言编写经验丰富的C程序员一样轻松快捷地编写程序。

也许是因为汇编编程与HLL完全不同,并且需要不同的思维,方法和方式,这使得对于不熟悉的编程变得很尴尬,因此给它起了不好的名字来编写程序。

如果可移植性不是问题,那么,对于像NASM这样的优秀汇编程序,C真的有什么呢?

编辑: 只是指出。当您使用汇编语言编写时,您不必只编写指令代码。您可以使用宏和过程以及您自己的约定来进行各种抽象,以使程序更具模块化,更可维护且更易于阅读。这是熟悉如何编写良好汇编的地方。


71
写?读代码呢?你(及其他)将读取的代码有很多很多比你写的

81
为什么我的程序要在新平台上运行,为什么我必须学习一种新语言?为什么我必须构造程序来适应CPU的想法,即有多少个寄存器以及您可以使用它做什么呢?我试图解决问题,不做电脑招标。
Joachim Sauer 2010年

8
编辑摘要:可以使用C编译器。
Meinersbur

4
@Simon也许那时我的岁月错了,但是令我们惊讶的是,我们在2010年将ASM与“像C这样的高级语言”进行辩论。具体来说,其中C是高级语言的示例
matt b

11
@changelog:那不是您拼写programming.reddit.com的方式。
BoltClock

Answers:


331

与高级语言相比,ASM的可读性较差,并且实际上不可维护

而且,与其他更流行的语言(例如C)相比,ASM开发人员得多。

此外,如果您使用高级语言并且有新的ASM指令可用(例如SSE),则只需更新编译器,您的旧代码即可轻松使用新指令。

如果下一个CPU的寄存器数量增加一倍该怎么办?

这个问题的反面是:编译器提供什么功能?

我怀疑您能否/希望/应该比自己更好地优化ASM gcc -O3


10
gcc在优化方面并不是那么出色,远胜于普通人,但是在很多地方,优化器都做得不好。否则同意您的意见。
old_timer 2010年

4
@dwelch在极少数情况下,gcc(或许多其他编译器)无法正确地优化已编译的C。但是,在这些情况下,您始终可以在ASM中编写有限数量的过程,并在构建过程中仅链接这些方法。
cortijon

@Ben S:我最初使用“很多”而不是“很多”进行编辑,因为“很多”仅用于单个对象。由于“很多”的对象是复数(开发人员),因此“很多”是正确的选择。但是,如果您想要的是“很多”,我将不再编辑您的答案。
Billy ONeal

1
在许多情况下,编译器无法很好地进行优化,但是,意识到优化器的局限性的开发人员常常可以在不借助汇编的情况下优化其C代码。
Qwertie

1
FWIW在我的日常工作中,我使用gcc -g -O0来编译我们的产品,因为能够将gdb附加到实时系统上,并且不会因优化变量而存在,这对他来说是个地狱这比每天增加40亿个CPU周期闲置(总数3万亿)要大得多。处理整数并不是经常出现的瓶颈。
伯恩德·詹德里塞克

1930

该死,我是编译器。

当您阅读此句子时,我刚刚扫描了数千行代码。我浏览了数百万种可能的方法,这些方法是基于数百种您将花费数年才能完成的学术研究,使用数百种不同的优化技术来优化您的单行的。当我将三行循环转换为成千上万条指令以使其更快时,我不会感到任何尴尬,甚至一点点都不会。我不羞耻地进行了大量的优化工作或进行最肮脏的技巧。如果您不希望我这样做,也许是一两天,我就会表现出来并按照您喜欢的方式进行。我可以随时更改我正在使用的方法,甚至无需更改代码的任何一行。我什至可以向您展示代码在汇编中的外观,如果您愿意,可以在不同的处理器体系结构,不同的操作系统以及不同的组装约定上使用。是的,只需几秒钟。因为,你知道,我可以;而且你知道,你做不到。

PS哦,顺便说一下,您没有使用所编写代码的一半。我帮了你一个忙,把它扔了。


99

我已经为6502,Z80、6809和8086芯片编写了大量汇编程序。一旦C编译器可用于我要处理的平台,我便停止这样做,并立即提高了至少10倍的生产率。大多数优秀的程序员出于理性原因都使用他们使用的工具。


72

我喜欢使用汇编语言进行编程,但是要完成与高级语言相同的工作,需要花费更多的代码,并且代码行和错误之间存在直接的关联。(这在几十年前的《神话人月》中进行了解释。)

可以将C视为“高级程序集”,但在此基础上走了几步,您就进入了另一个世界。在C#中,您无需三思而后行:

foreach (string s in listOfStrings) { /* do stuff */ }

这将是数十行,甚至数百行代码的汇编,每个实现它的程序员都将采用不同的方法,而下一个人将不得不弄清楚它。因此,如果您相信(就像许多人一样)程序主要是供其他人阅读的,则汇编程序比典型的HLL可读性差。

编辑:我积累了用于日常任务的个人代码库,以及用于实现类似C的控制结构的宏。但是在90年代,当GUI成为标准时,我碰壁了。在例行事务上花了太多时间。

我对ASM至关重要的最后一项任务是几年前,编写代码来对抗恶意软件。没有用户界面,因此所有这些都很有趣,而且没有膨胀。


你确定吗?我似乎还记得在Code Complete中读到的情况并非如此……
jcolebrand

1
我敢肯定,“过早优化”的劣势会击败“少行”的优势。但是我好久没有看代码完善了……
egrunin

6
有点讽刺意味使用“过早优化”作为参数汇编...(我可能误解了你,虽然我仍然认为这很有趣。)
贝恩德Jendrissek

您仍然可以在汇编器中调用函数,因此我怀疑foreach循环需要数十行到数百行。还是我想念什么?
塞巴斯蒂安·马赫

@phresnel:foreach比起for- 做更多的工作-它实例化并使用特定于类型的迭代器。
egrunin 2012年

15

除了其他人对可读性,可维护性,较短的代码(从而减少错误)并且更容易实现的答案之外,我还要添加一个其他原因:

程序速度。

是的,在汇编中,您可以手动调整代码以利用每个上一个周期,并使其在物理上尽可能快。但是谁有时间?如果您编写的不是完全愚蠢的C程序,则编译器将为您做一个非常好的优化工作。大概可以手动完成至少95%的优化,而不必担心跟踪任何优化。这里肯定有90/10的规则,其中最后5%的优化最终将占用您95%的时间。那为什么要打扰呢?


4
+1。编写汇编代码和编写快速汇编代码是两件事。如果使用好的编译器,则可以免费获得快速的汇编代码。
Niki 2010年

仅当您知道如何使用编译器,大多数人不使用优化,大多数人使用调试选项进行编译时,您才能免费获得快速汇编器代码,结果,结果是做得不好的慢速汇编器。是的,超过99%的时间您不应该触摸它,只需触摸编译器旋钮,而不直接调整输出即可。
old_timer 2010年

如果您在乎优化,那么您应该从编译器执行此操作...如果您不在乎优化,但是您仍在使用汇编,那您就傻了。
Brian Postow'4

@dwelch:我猜可能有些脚本小子会不费吹灰之力找出使用工具的方式。但是我怀疑像他们这样的人是否能够编写快速的汇编代码。
Niki

13

如果一个普通的生产程序有10万行代码,而每一行大约是8到12条汇编程序指令,那将是一百万条汇编程序指令。

即使您可以以适当的速度手工编写所有这些内容(请记住,它是编写代码的8倍),但是如果您想更改某些功能会怎样?从几百万条指令中了解几周前您写的内容真是一场噩梦!没有模块,没有类,没有面向对象的设计,没有框架,什么都没有。即使是最简单的事情,您必须编写的看起来相似的代码充其量也令人望而生畏。

此外,您无法像高级语言一样优化您的代码。例如,在C语言中执行疯狂的优化是因为您描述了自己的意图,不仅是代码,在汇编器中您仅编写代码,而汇编器实际上无法对代码执行任何值得注意的优化。您所写的就是所得到的,并且请相信我,您无法可靠地优化在编写时修补和修补的100万条指令。


8

好吧,“过去”我一直在写很多程序集,并且可以向您保证,当我用高级语言编写程序时,我的工作效率更高。


8
“大会是拉丁文的”。
阿德里亚诺瓦里里广场

4
@Adriano:除了有许多不同的方言,而且没有两个看起来相似。
Joachim Sauer 2010年

1
当然可以,但是我的意思是,学习其中的任何一种程序都可以使您深入了解可以帮助您更高水平的计算机体系结构。除非您处理分页内存,否则那样的话您将很伤痕累累。就像从Catullus读Carmen 16一样。
阿德里亚诺瓦里里广场

5
@Adriano,“汇编是拉丁文”,没有asm是穴居人的咕unt声。一块岩石咕gr一声,鹿的咕gr咕fire声,火的咕gr声咕3三声-简单的东西好,但很难建立帝国。
马丁·贝克特

1
@马丁:您是否曾经尝试使用罗马数字进行复杂的算术运算?
阿德里亚诺瓦里里广场

6

汇编能力的合理水平是一个有用的技能,特别是如果你在任何类型的系统级或嵌入式编程工作,与其说是因为你写那么多汇编,而是因为有时要明白什么是框是很重要的真的做。如果您对汇编器的概念和问题不了解,那么可能会很难。

但是,至于实际上在汇编器中编写了很多代码,有很多原因导致它做得不好。

  • 根本没有(几乎)需要。除了像早期的系统初始化之类的东西以及隐藏在C函数或宏中的一些汇编器片段外,所有曾经曾经用汇编器编写的非常低级的代码都可以毫不费力地用C或C ++编写。

  • 用高级语言(甚至C和C ++)编写的代码将功能浓缩到少得多的行中,并且有大量研究表明,错误的数量与源代码的数量相关。即,在汇编器和C中解决的同一问题,仅是因为其较长,就会在汇编器中出现更多错误。相同的论点促使人们转向高级语言,例如Perl,Python等。

  • 用汇编器编写时,您必须处理问题的各个方面,从详细的内存布局,指令选择,算法选择,堆栈管理等开始。高级语言使您无法使用所有这些,这就是为什么它们如此密集的原因LOC条款。

本质上,以上所有内容都与汇编程序对比C或其他某种语言所提供的抽象级别有关。汇编程序迫使您创建自己的所有抽象,并通过自己的自律来维护它们,在这种情况下,任何中级语言(例如C),尤其是高级语言,都可以为您提供现成的抽象,以及相对容易地创建新功能的能力。


6

作为一个将大部分时间都花在嵌入式编程世界上的开发人员,我认为汇编语言远非一成不变的语言。存在某些接近金属的编码级别(例如,在驱动程序中),有时无法用高级语言准确或有效地表示。我们几乎用汇编器编写所有的硬件接口例程。

话虽如此,该汇编代码被包装起来,以便可以从C代码中调用它,并将其视为库。由于种种原因,我们没有在汇编中编写整个程序。首先是可移植性;我们的代码库在使用不同体系结构的几种产品上使用,我们希望最大化它们之间可以共享的代码量。其次是开发人员的熟悉程度。简而言之,学校没有像过去那样教授汇编语言,而且我们的开发人员在C语言方面的效率远高于汇编语言。另外,我们有很多“附加”(例如库,调试器,静态分析工具等)可用于我们的C代码,而汇编语言代码则不可用。即使我们想编写一个纯汇编程序,我们将无法执行,因为几个关键的硬件库仅作为C库提供。从某种意义上说,这是鸡/蛋的问题。人们被迫离开汇编语言,因为没有太多可用的库和开发/调试工具,但是库/工具不存在,因为没有足够的人使用汇编语言来保证创建汇编语言的努力。

最后,几乎所有语言都有时间和地点。人们使用他们最熟悉和最有生产力的东西。在程序员的汇编库中可能总会有一个地方,但是大多数程序员会发现,他们可以用高级语言编写代码,而这种语言几乎可以用更少的时间获得相同的效率。


6

当您使用汇编语言编写时,您不必只编写指令代码。您可以使用宏和过程以及您自己的约定来进行各种抽象,以使程序更具模块化,更可维护且更易于阅读。

因此,您基本上要说的是,通过熟练地使用复杂的汇编器,可以使ASM代码越来越接近C(或者无论如何是您自己发明的另一种低端语言),直到最终您只是和C程序员一样有生产力。

这是否回答你的问题?;-)

我并不是说这个闲话:我已经使用这样的汇编器和系统进行了编程。更好的是,汇编程序可以将目标定为虚拟处理器,然后一个单独的转换器为目标平台编译汇编程序的输出。LLVM的IF发生了很多事情,但是它的早期形式要早10年左右。因此,它具有可移植性,以及为提高效率而为特定目标组装商编写例程的能力。

使用该汇编器编写代码的效率与C差不多,并且与GCC-3(在我参与此过程时差不多)进行比较,汇编器/翻译器产生的代码大致一样快,通常较小。规模真的很重要,公司几乎没有程序员,并且愿意在新员工做任何有用的事情之前教他们新的语言。我们有一个备份,那些不了解汇编程序的人(例如客户)可以编写C并使用相同的调用约定等在同一个虚拟处理器中对其进行编译,从而使C进行整齐的接口。因此,这感觉像是一场微弱的胜利。

那是在开发组装技术,库等方面花费了多年的精力。不可否认的是,其中很多都用于使其具有可移植性,如果它只是针对一种体系结构,那么全力以赴的全舞蹈汇编程序会容易得多。

总结:您可能不喜欢C,但这并不意味着使用C的努力要比提出更好的努力更大。


5

组装不能在不同的微处理器之间移植。


对于现代处理器和汇编程序而言,这并不是完全正确的,您可以像在C语言中那样针对不同的处理器。确保在这种情况下,您将无法使用全部指令,但是如果您编写,则也不会使用可移植性不是主要问题。
Blindy 2010年

6
也许你是说建筑
本S

2
@Blindy-您可以针对x86系列中的不同处理器,但是x86变体与ARM处理器或Z80或8051之间的汇编指令中肯定没有通用性
。– semaj 2010年

是的,但是您也无法在C中编写z80。我认为我们在这里都在谈论普通的x86 / x64处理器。
Blindy

1
全世界不是x86。关于“不同的微处理器”的任何内容都没有暗示它们都执行相同的指令集。
伯恩德·詹德里塞克

5

同样的原因,我们不再去外面的浴室,或者为什么我们不会讲拉丁语或阿拉姆语。

技术的出现使事情变得更容易和更容易获得。

编辑-为了停止冒犯他人,我删除了某些单词。


4
您仍在冒犯Luddites这个词Technology
SeanJA

1
“我们”不会讲拉丁语吗?
dank

拉丁语和阿拉姆语都没有消失,因为它们被更好的技术(即更容易学习/使用的语言)所取代。实际上,拉丁语在欧洲各地仍然与我们同在。所有罗马语言都基于拉丁语。今天,近50万人使用现代(新)阿拉姆语。这些语言不再盛行的原因是历史性的(更确切地说是地缘政治性的),而不是技术性的。同样的原因,英语是我们这个时代的科学和统治阶级的通用语言-上个帝国的人民,英国人(现在是美国美国人)会说英语。
丽思酒店

4

为什么?简单。

比较一下:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

它们在功能上是相同的。第二个甚至不是汇编器,而是.NET IL(中间语言,类似于Java的字节码)。第二次编译将IL转换为本机代码(即几乎是汇编程序),使其更加难以理解。


3

我想即使在x86(_64)上使用ASM在通过利用编译器难以优化的指令获得大量收益的情况下也是有意义的。例如,x264使用大量的asm进行编码,因此速度提升非常明显。


2

我敢肯定有很多原因,但是我能想到的两个快速原因是

  1. 汇编代码肯定更难阅读(我很肯定它也更耗时)
  2. 当您拥有庞大的产品开发团队时,将代码分成逻辑块并由接口保护会很有帮助。

1
注意,您也可以将程序集分为逻辑块。
保罗·威廉姆斯

2

早期发现之一(您会在Brooks的Mythical Man-Month中找到它,它是从1960年代的经验中得出的),人们每天在经过调试的代码行中使用一种语言的效率与另一种语言差不多。这显然不是普遍适用的,并且如果推得太远可能会中断,但这在布鲁克斯时代的高级语言中通常是适用的。

因此,提高生产率的最快方法是使用一种语言,其中一行代码可以完成更多工作,并且至少对于FORTRAN和COBOL之类的复杂语言,这确实有效,或者给出一个更现代的示例C。


2

可移植性始终是一个问题-至少现在不是现在,至少不是现在。编程行业每年花费数十亿美元来移植旧软件,而在编写旧软件时,“显然”没有任何可移植性问题。


2
“它不必移植到另一种体系结构”在我耳边听起来像是“一年不需要超过两位数字”。
David Thornley 2010年

还是因为Windows可能不在明年左右而不能使用C#?
马丁·贝克特

例如,苹果的MacIntosh计算机基于Motorola MC68000系列处理器,PowerPC(IBM等),以及现在的Intel x86(IA-32(e))处理器。所以是的,对于任何使用时间足够长的系统来说,可移植性都是一个问题,并且尚未受到代码持续时间长于预期的任何程序员的困扰。
mctylr 2010年

@Martin:从现在开始的二十年里,将会有很多人们想要运行的C#程序,因此将有一种编译和运行C#程序的方法。C#并没有固有的固定方法,尽管二十年来,如果它仍然像现在这样流行,我会感到惊讶。但是,在二十年后,我们的CPU将大为不同。写于1990年的汇编程序可能运行时下,但它肯定不会是最佳的,而且会比编译C.运行速度较慢
大卫·索恩利

那就是我的意思-我有更多的移植问题,因为高级框架比6个月前有所改变,因为x86中的指令发生了变化-特别是因为手工编码的asm倾向于坚持最简单的方法。
马丁·贝克特

2

随着汇编变得越来越不普遍,出现了一个恶性循环:随着高级语言的成熟,汇编语言指令集的构建为程序员带来的便利越来越少,而为编译器带来的便利却越来越多。

因此,实际上,现在可能很难做出正确的决定,例如,应该使用哪些寄存器或哪些指令效率更高。编译器可以使用启发式方法找出哪些折衷方案可能会获得最佳收益。我们可能可以考虑一些较小的问题,找到可以胜过我们现在非常复杂的编译器的局部优化,但是奇怪的是,在一般情况下,一个好的编译器比起一个好的程序员,在第一次尝试时会做得更好。最终,像约翰·亨利一样,我们可能会击败机器,但可能会严重烧伤自己。

现在我们的问题也大不相同。1986年,我试图弄清楚如何从涉及在屏幕上放置几百个像素的小程序中获得更高的速度。我希望动画不那么生涩。汇编语言的合理案例。现在,我正在尝试弄清如何表示有关抵押贷款的合同语言和服务商政策的抽象概念,而我希望阅读一些类似于商务人士所讲语言的东西。与LISP宏不同,汇编宏不会以规则的方式强制执行很多操作,因此,即使您可以在良好的汇编程序中获得与DSL相当接近的东西,也很容易发生各种奇怪的事情。如果我用Ruby,Boo,Lisp,C#甚至F#编写相同的代码,不会给我带来麻烦。

但是,如果您的问题很容易用高效的汇编语言表达,那么您将获得更大的权力。


2

同上大多数人所说的话。

在C发明之前的美好时光中,当唯一的高级语言是诸如COBOL和FORTRAN之类的东西时,有很多事情如果不依靠汇编器是不可能完成的。这是获得全部灵活性,能够访问所有设备等的唯一方法。但是后来发明了C,几乎所有在汇编中可能的事情都可以用C进行。然后。

就是说,对于新程序员来说,学习汇编语言编写是非常有用的练习。不是因为他们实际上会大量使用它,而是因为您随后了解了计算机内部真正发生的情况。我从程序员那里看到了许多编程错误和低效率的代码,这些程序员显然不知道位,字节和寄存器到底发生了什么。


是的,当场。几年前,IBM大型机上的Fortran磁盘和磁带I / O几乎是无用的,因此我们在370 / Assembler中编写了自己的I / O例程,并从Fortan IV代码中对其进行了调用。编写汇编代码使我真正了解了基础架构。我已经有好几年没有写任何汇编代码了,与我一起工作的所有年轻人都从未写过任何汇编代码-但是我希望他们会写,这是如此有教育意义。
西蒙·

2

我已经在汇编中编程了大约一个月。我经常用C语言编写一段代码,然后将其编译为汇编程序以帮助我。也许我没有利用C编译器的全部优化功能,但看来我的C asm源中包括不必要的操作。因此,我开始看到关于好的C编译器胜过好的汇编编码器的说法并不总是正确的。

无论如何,我的汇编程序是如此之快。而且我使用汇编的次数越多,编写代码所花费的时间就越少,因为这并不难。同样,关于汇编的可读性差的评论也不正确。如果您正确地标记了程序并在需要其他详细说明时发表评论,那么您应该准备就绪。实际上,对于程序员而言,汇编的方式更加清晰,因为他们可以看到处理器级别上正在发生的事情。我不了解其他程序员,但对我来说,我更喜欢知道正在发生的事情,而不是把事情弄成黑匣子。

这样说来,编译器的真正优势在于,编译器可以理解模式和关系,然后在源代码的适当位置自动对其进行编码。一个流行的例子是C ++中的虚函数,它要求编译器以最佳方式映射函数指针。但是,编译器只能进行编译器制造商允许编译器执行的操作。这导致程序员有时不得不诉诸于用代码做一些奇怪的事情,增加编码时间,而这本来可以用汇编来完成的。

我个人认为市场在很大程度上支持高级语言。如果汇编语言是当今唯一存在的语言,那么他们的编程人员和知道我们的世界的人将减少大约70%,大概是90年代。高级语言吸引了更广泛的人群。这允许更多的程序员来构建我们这个世界所需的基础架构。像中国和印度这样的发展中国家从Java等语言中受益匪浅。这些国家将快速发展其IT基础架构,人们之间的联系将会更加紧密。因此,我的观点是,高级语言之所以流行,不是因为它们产生了出色的代码,而是因为它们有助于满足世界市场的需求。


+1表示黑匣子。是的,我们正在使用黑匣子,无法窥视它们(太简单了)。C#foreach如何真正起作用?谁知道。微软表示,这是完美的。那一定是。
ern0

同样,不要忘记,“高级语言”还带来了现实世界中许多其他重要内容。C附带了标准库(数学,字符串处理,I / O等),然后像Java这样的重量级文件附带了许多用于连接,图像处理,数据处理,Web开发等的其他程序包和库。用你的时间来专注于获得1个详细的任务在一个平台上具有高性能的(因而使用汇编)与消费的同时获得一个以最小的错误多个平台上运行更重要的任务。
jbx

1

我现在正在comp org中学习汇编,虽然很有趣,但是编写效率也很低。您必须在头脑中保留更多细节才能使工作正常进行,并且编写相同事物的速度也较慢。例如,在C ++中,简单的6行for循环可以等于18行或更多行的汇编。

就个人而言,学习硬件在硬件上如何工作是一件很有趣的事,它使我对计算的工作方式有了更大的了解。


1

C语言比C语言具有更好的宏汇编器。类型检查。循环构造。自动堆栈管理。(几乎)自动变量管理。汇编程序中的动态内存技术是一个巨大的难题。与C或更好的列表foo.insert()相比,正确地创建链接列表只是令人恐惧。和调试-好吧,在什么方面更容易调试没有竞争。HLL在那赢得胜利。

我已经将近一半的职业生涯用汇编语言编写,这使我很容易想到装配工。它可以帮助我了解C编译器在做什么,这又可以帮助我编写C编译器可以有效处理的代码。经过深思熟虑的用C编写的例程可以编写出来,只需花费很少的工作即可输出所需的汇编程序,而且它是可移植的!由于跨平台的原因,我已经不得不将一些较旧的asm例程改写回C,这很有趣。

不,我会坚持使用C并处理偶尔出现的性能下降(相对于HLL获得的生产力时间)。


1

我只能回答为什么我个人不经常在汇编中编写程序,而主要原因是这样做比较繁琐。另外,我认为在不立即注意到的情况下更容易发现错误。例如,您可能会在一个例程中更改使用寄存器的方式,但是忘记在一处更改它。它会很好地组装,您可能要等到很久以后才能注意到。

就是说,我确实认为汇编仍然有有效的用途。例如,我使用SIMD并遵循偏执的“每一位都是神圣的” [quote V.Stob]方法,有许多用于处理大量数据的相当优化的汇编例程。(但是请注意,幼稚的程序集实现通常比编译器为您生成的实现要差得多。)


1

C是宏汇编程序!这是最好的之一!

它几乎可以完成所有汇编程序,可以移植,并且在大多数罕见的情况下,它不能执行某些操作,您仍然可以使用嵌入式汇编代码。这样只剩下一小部分您绝对需要用汇编语言编写的程序,而无非是汇编语言。

而且更高层次的抽象性和可移植性使大多数人都可以用C编写系统软件。尽管现在如果您花费大量时间和金钱来编写某些程序,则可能不需要可移植性,但是您可能不想限制自己将来您将可以使用它。


1

人们似乎忘记了还有另一个方向。

您为什么首先要在Assembler中写作?为什么不使用真正的低级语言编写程序?

代替

mov eax, 0x123
add eax, 0x456
push eax
call printInt

你也可以写

B823010000
0556040000
50 
FF15.....

这样有很多优点,您知道程序的确切大小,可以将指令的值重用作为其他指令的输入,甚至不需要汇编程序来编写它,就可以使用任何文本编辑器...

您仍然偏爱汇编程序的原因是其他人偏爱C ...


0

因为总是这样:时间消逝,美好的事物也消逝:(

但是,当您编写asm代码时,与编写高级lang时的感觉完全不同,尽管您知道它的生产效率要低得多。就像您是画家一样:您可以自由地以自己喜欢的方式绘画任何东西,而没有任何限制(嗯,仅受CPU功能限制)...这就是为什么我喜欢它。可惜的是这种语言消失了。但是,尽管有人仍然记得它并对其进行编码,但它永远不会死!


真正。另一方面,当收银员和超市拒绝兑现支票时,您会感到羞辱,轻蔑地说:“哦,您使用低级语言编程。”
杰伊,2010年

0

$$$

一家公司雇用开发人员来帮助将代码转换为$$$。更快的是有用的代码可以产生,更快的公司可以把该代码转换成$$$。

更高级别的语言通常更适合于生产大量有用的代码。这并不是说大会没有它的位置,因为在某些时候和地方,别无他法。


0

当您将程序集与比C更高级的语言进行比较时,例如Java或Python或Ruby,HLL的优势甚至更大。例如,这些语言具有垃圾回收功能:无需担心何时释放一块内存,也不必担心由于过早释放而导致的内存泄漏或错误。


0

如前所述,任何工具存在的原因是它的工作效率。由于HLL可以完成与许多行asm代码相同的工作,我想很自然地可以将汇编语言替换为其他语言。并且对于接近硬件的摆弄-使用C语言进行内联汇编,以及根据语言的其他变体。Paul Carter博士用PC汇编语言说

“ ...比Pascal等编程语言更好地了解计算机的工作原理。通过对计算机如何工作有更深入的了解,读者通常可以使用C等高级语言开发软件,从而提高生产力。和C ++。学习使用汇编语言进行编程是实现此目标的绝佳方法。”

我们在大学课程中对组装进行了介绍。这将有助于清除概念。但是我怀疑我们中的任何人都将在汇编中编写90%的代码。今天,深入的装配知识有多重要?


-2

翻阅这些答案,我敢打赌9/10的响应者从未使用过汇编程序。

这是一个古老的问题,每隔一段时间就会出现一次,您会得到相同的答案,大多数都是错误的答案。如果不是为了可移植性,我仍然会自己组装所有东西。即使那样,我也几乎像在汇编中那样用C编写代码。


1
+1提及没有任何asm经验的人,另一个+1应该代表“使用asm在C语言中编码”。当我为嵌入式编写C ++(是的,CPP,不是C)应用程序时,我的编码就像是asm,例如,根本不使用new / malloc()。
ern0

因此,您使用了很多诸如char buf [MAX_PATH]之类的东西,当有人拥有MAX_PATH + n大小的数据时,这些东西就会掉落吗?;)
paulm

1
@paulm-您的意思是就像C一样吗?
罗布

1
我当然希望汇编程序作者不要避免使用malloc()。是的,在嵌入式系统中,您受内存限制。但是,在Unix或其他台式机(甚至大多数移动操作系统)上执行此操作,您将不必要地限制自己和用户。另外:编写的LOC越少,出错的机会就越少,这意味着较高级别的代码可能比较低级别的代码少。
uliwitness

1
只是看了一下,因为我很怀疑,是的,我确定可以告诉Redditor和HNers在这里。
罗布
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.