汇编编程比高级语言(如c)花费更长的时间,更难编程,这似乎是一种主流观点。因此,出于这些原因以及更好的可移植性,似乎建议或假设用高级语言编写更好。

最近我一直在用x86汇编语言写作,我开始意识到这些原因可能都不是真的,除了可移植性。也许这更多的是一个熟悉的问题,知道如何写好汇编。我还注意到在汇编中编程与在HLL中编程有很大的不同。也许一个好的、有经验的汇编程序员可以像一个有经验的C程序员用C写程序一样轻松、快速地编写程序。

也许是因为汇编编程与hll有很大的不同,因此需要不同的思维、方法和方式,这使得对不熟悉的人编写程序看起来非常尴尬,因此给汇编编程带来了不好的名声。

如果可移植性不是问题,那么C语言比NASM这样的优秀汇编器有什么优势呢?

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


当前回答

为什么?简单。

比较一下:

        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();
        }

with

.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转换为本地代码(即几乎是汇编程序),使其更加神秘。

其他回答

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

为什么你一开始要用汇编语言写东西?为什么不用一种真正低级的语言来编写程序呢?

而不是

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

你还是写吧

B823010000
0556040000
50 
FF15.....

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

你仍然喜欢汇编程序的原因,是其他人喜欢C语言的原因。

我喜欢用汇编语言编程,但是用高级语言做同样的事情需要更多的代码,而且代码行和错误之间有直接的联系。(这在几十年前的《人月神话》中就有解释。)

可以把C语言看作是“高级汇编”,但再往上走几步,你就进入了另一个世界。在c#中,你不需要三思就可以写这样的代码:

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

这将是几十行,甚至几百行的汇编代码,每个实现它的程序员将采用不同的方法,下一个来的人将不得不找出它。因此,如果您相信(许多人都相信)程序主要是为其他人阅读而编写的,那么汇编的可读性就不如典型的HLL。

编辑:我积累了一个用于常见任务的个人代码库,以及用于实现类c控制结构的宏。但在90年代,当gui成为常态时,我遇到了瓶颈。太多的时间被花在了例行公事上。

我的上一个需要使用ASM的任务是在几年前,编写代码来对抗恶意软件。没有用户界面,所以只有有趣的部分,没有臃肿的部分。

我已经为6502、Z80、6809和8086芯片编写了大量的汇编程序。当C编译器在我所处理的平台上可用时,我就停止了这样做,并且立即提高了至少10倍的生产力。大多数优秀的程序员使用他们所使用的工具是出于合理的原因。

与高级语言相比,ASM的易读性很差,而且实际上难以维护。

此外,ASM开发人员比其他更流行的语言(如C)要少得多。

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

如果下一个CPU有两倍多的寄存器呢?

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

我怀疑你能够/想要/应该比gcc -O3更好地优化你的ASM。

正如其他人之前提到的,任何工具存在的原因都是它的工作效率。由于hll可以完成与许多行asm代码相同的工作,我想汇编被其他语言取代是很自然的。对于接近硬件的操作——有C语言的内联汇编和每种语言的其他变体。 保罗·卡特博士在PC汇编语言中说

"...更好地理解如何 计算机实际上是在较低的水平上工作的 而不是编程语言 帕斯卡。通过获得更深层次的 了解计算机的工作原理, 读者通常可以做得更多 生产开发软件 高级语言,如C和 c++。学习汇编编程 语言是一种极好的方法 实现这个目标。”

在我的大学课程中有装配入门。这将有助于理清概念。然而,我怀疑我们中是否有人会用汇编编写90%的代码。今天深入的组装知识有多大的相关性?