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

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

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

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

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


当前回答

我现在正在comp组织学习汇编,虽然它很有趣,但它也非常低效。你必须在脑子里记住更多的细节才能让事情顺利进行,而且写同样的东西也会慢一些。例如,c++中一个简单的6行For循环可以等于18行或更多的汇编。

就我个人而言,学习硬件层面的工作方式非常有趣,它让我对计算的工作方式有了更多的了解。

其他回答

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

因此,您基本上是在说,通过熟练地使用复杂的汇编程序,您可以使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语言的努力就比想出更好的东西的努力更大。

汇编在不同的微处理器之间是不可移植的。

C语言优于一个好的宏汇编器的地方是C语言类型检查。循环结构。自动栈管理。(几乎)自动变量管理。动态内存技术在汇编是一个巨大的痛苦在屁股。与C或更好的foo.insert()列表相比,正确地执行链表是非常可怕的。还有调试——嗯,谁更容易调试谁也不存在争议。他们在那儿轻而易举就赢了。

我几乎一半的职业生涯都是用汇编程序编写的,这让我很容易用汇编程序思考。它帮助我了解C编译器在做什么,这再次帮助我编写C编译器可以有效处理的代码。用C编写的一个经过深思熟虑的例程可以在汇编程序中输出你想要的东西——而且它是可移植的!由于跨平台的原因,我已经不得不将一些旧的asm例程重写回C,这并不有趣。

不,我将坚持使用C,并处理与使用HLL获得的生产时间相比偶尔出现的轻微性能放缓。

不同之处在于,汇编程序是一门代码的艺术,是一幅出自艺术家之手的好画。你比蹩脚的编译器代码聪明吗?如果你是,使用它或照顾你的绘画与c和汇编一起。

为什么?简单。

比较一下:

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