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

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

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

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

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


当前回答

除了其他人对可读性、可维护性、更短的代码从而更少的错误和更简单的回答之外,我还将添加一个额外的原因:

程序的速度。

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?

其他回答

$$$

一家公司雇佣一名开发人员来帮助将代码转化为$$$。越快地生成有用的代码,公司就能越快地将代码转化为利润。

高级语言通常更擅长生成大量有用的代码。这并不是说集会没有它的位置,因为在有些时候和地方,没有别的方法可以。

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

即使您可以以相当快的速度手写所有这些代码(请记住,这是您必须编写的8倍代码),如果您想更改某些功能会发生什么?从这100万条指令中理解你几周前写的东西简直是一场噩梦!没有模块,没有类,没有面向对象的设计,没有框架,什么都没有。即使是为最简单的事情编写的类似代码的数量最多也令人生畏。

此外,你不能像高级语言那样优化你的代码。例如,C语言执行了大量的优化,因为你描述了你的意图,不仅仅是你的代码,在汇编程序中你只写代码,汇编程序不能对你的代码执行任何值得注意的优化。你写的就是你得到的,相信我,你不可能可靠地优化100万条指令,你在写的时候不断地打补丁。

为什么?简单。

比较一下:

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

C是一个宏汇编器!这是最好的一个!

它可以做几乎所有汇编程序可以做的事情,它是可移植的,在大多数极少数情况下,当它不能做一些事情时,你仍然可以使用嵌入式汇编代码。这就只留下了一小部分程序,你绝对需要用汇编来编写,而且只需要汇编。

更高层次的抽象和可移植性使大多数人更值得用c语言编写系统软件。尽管你现在可能不需要可移植性,但如果你在编写某个程序上投入了大量的时间和金钱,你可能不想把自己限制在将来可以使用它的地方。

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

因此,您基本上是在说,通过熟练地使用复杂的汇编程序,您可以使ASM代码越来越接近C(或者您自己发明的另一种低级语言),直到最终您的工作效率与C程序员一样高。

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

我并不是在无所事事地说:我已经使用这样的汇编器和系统进行了编程。更好的是,汇编程序可以以虚拟处理器为目标,并且一个单独的翻译程序可以为目标平台编译汇编程序的输出。与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语言,但这并不意味着使用C语言的努力就比想出更好的东西的努力更大。