是否可以为所有计算机提供通用汇编语言?


23

我想问一些关于汇编语言的问题。我的理解是,它与机器语言非常接近,从而使其更快,更高效。

由于我们存在不同的计算机体系结构,这是否意味着我必须在Assembly中针对不同的体系结构编写不同的代码?如果是这样,为什么汇编不写一次-到处运行类型的语言?简单地使其具有通用性,只编写一次就可以在几乎任何具有不同配置的机器上运行,难道不是一件容易的事吗?(我认为这是不可能的,但是我想提出一些具体,深入的答案)

有人可能会说C是我要寻找的语言。我以前没有使用过C,但是我认为它仍然是一种高级语言,尽管可能比Java快。我可能在这里错了。


10
你做了什么研究?我们希望您在提出问题之前先进行研究,以帮助您提出更好的问题。有很多关于汇编语言的文章。
DW

4
我们希望您在询问之前进行大量的研究/自学,并在问题中告诉我们您进行了哪些研究。在这种情况下,研究可能包括阅读相关的维基百科文章(例如,有关汇编语言和计算机体系结构的文章)和阅读计算机体系结构的教科书。要提出一个更好的问题:进行研究(如果尚未进行),然后编辑问题以解释您已完成的研究。通常,这种研究可以帮助您提出一个更好的问题。在任何情况下都可以帮助答题者避免重复您已经知道的内容。
DW

15
首先了解/为什么没有一种语言称为汇编。
拉斐尔

2
C可移植性的一个“经典”问题是不同硬件上的原语(例如整数)大小不同,还有其他一些引用。
vzn 2015年

3
与技术问题相比,这更是一个社会问题-您需要说服所有CPU制造商使它们的CPU接受相同的机器语言。(实际上,x86几乎是偶然的,然后是智能手机起飞了)
user253751

Answers:


45

汇编语言是一种为计算机指令集编写指令的方式,这种方式对于人类程序员来说更容易理解。

不同的体系结构具有不同的指令集:每种体系结构上允许的指令集不同。因此,您不希望拥有一个随处运行的编写程序。例如,x86处理器支持的指令集看起来与ARM处理器支持的指令集非常不同。如果您为x86处理器编写了汇编程序,则其中将包含ARM处理器不支持的许多指令,反之亦然。

使用汇编语言的核心原因是,它允许对程序进行非常低级的控制,并利用处理器的所有指令:通过自定义程序以利用特定处理器特有的功能,可以对程序进行优化。将继续运行,有时您可以加快程序运行速度。一次写入,到处运行的哲学从根本上与这一观点背道而驰。


1
我认为这个问题已经在答案的第3段中得到了回答。就像您说的那样,这样的方案效率不高,因此与使用汇编语言的核心原因根本不符。
DW

26
@nTuply一旦您修改了汇编语言以适应不同的机器,它便成为具有可怕的汇编样式语法的高级语言。一旦决定使用一种高级语言,就可以使用一种具有更友好语法的语言,并让编译器完成艰苦的工作。
David Richerby 2015年

15
拥有为不同机器翻译的“汇编语言”并不是一个完全愚蠢的主意,因为从根本上讲,这就是LLVM的“ IR”。但是,由于David给出的原因,您通常不编写 LLVM程序集。同样因为在100中有99倍,您编写它的工作要比将C转换为LLVM的clang做得糟。汇编语言可能比高级语言更有效,但是在大多数实际的程序员手中,典型的时间是可以优化的,但它们仍然无法发挥其潜力。
史蒂夫·杰索普

9
@nTuply,存在。从这种额外的汇编语言转换为机器指令的过程称为编译。
Paul Draper

3
@PJTraill除了在现代系统中的第一个自举步骤(大部分时间,甚至没有)之外,没有任何理由在现代系统上的汇编器中编写编译器。写在高级语言编译器是大大更有可能实际上是维护。还要比较用C语言编写编译器的语言如何比C语言更快?。编译器的目的是将一种语言(源语言)转换为另一种语言(通常是针对特定体系结构和OS的机器语言);可以用任何语言编写。
CVn

13

汇编语言的定义是它是一种可以直接转换为机器代码的语言。汇编语言中的每个操作代码都将转换为目标计算机上的一个正确操作。(嗯,这要复杂得多:一些汇编程序会根据操作码的参数自动确定“寻址模式”。但是,原理仍然是,一行汇编程序可以转换为一条机器语言指令。)

毫无疑问,您可以发明一种看起来像汇编语言但可以在不同计算机上转换为不同机器代码的语言。但是根据定义,那不是汇编语言。这将是类似于汇编语言的高级语言。

您的问题有点像在问:“有可能制造出一只不漂浮或没有其他方式越过水,但有轮子和电动机并且可以在陆地上行驶的船吗?” 答案将是,按照定义,这种车辆将不是船。听起来更像汽车。


1
C通常被描述为“便携式汇编语言”。
拉里·格里茨

2
@LarryGritz当然。当C发明时,它具有开创性的意义:它提供了汇编语言的强大功能,并且易于使用编译器。但是根据定义,它仍然是一种编译语言
Jay

8

没有概念上的理由(我敢说,没有计算机科学)反对世界上所有计算机都使用一种汇编语言。实际上,这会使许多事情变得容易得多。就理论而言,无论如何,直到某些时髦的双射,它们都是一样的。

然而,实际上,有不同的芯片用于不同的目的,具有不同的操作和设计原则(例如RISC vs CISC),它们可以满足不同的目标,并且操作它们的指令集以及汇编语言也不同。最后,答案与询问为什么有这么多不同的编程语言时是相同的:不同的目标,不同的设计决策。

也就是说,您当然可以引入抽象级别来访问某些共享接口。例如,x86已经在片上级别上被淘汰了很长时间。有一点硬件可以将x86指令转换为您的处理器真正可以使用的任何东西。诸如C之类的语言将离硬件(如果说很小的话)又一步之遥,直至像Haskell,Java或Ruby之类的语言。是的,编译器是计算机科学的主要成就之一,因为它们使以这种方式分离问题成为可能。


6
“如果可以说很小的话” –那里有您的两种程序员。那些因为C的基本操作而将C视为低级语言的人看起来很像CPU指令集中出现的事物,而那些将C 视为与计算机不同的指令集而将C视为高级语言的人。
史蒂夫·杰索普

如果用汇编语言表示完全控制为特定类型(或家族)硬件生成的机器代码,则可以在给定的时刻为我们的世界“为所有计算机”定义一种语言,但是它将必须不断变化。诚然,如果设计得当,它将缩短为新体系结构编码的学习曲线,但是我希望您要使用它做的任何工作,而不是编译器仅适用于一小部分体系结构。计算机在抽象级别上是相同的,这是一条红鲱鱼,它与机器代码有关。
PJTraill 2015年

7

您提到短语“一次写入就可以在任何地方运行”而似乎没有注意到它的重要性。这是营销口号为Sun Microsystems公司是商业发明了一个概念“虚拟机”“字节码”为Java,尽管可能的想法可能起源于学术界1 。在后来因违反Java许可侵权而被Sun成功起诉后,该想法后来被Microsoft复制为.Net。Java字节码是跨机器汇编或机器语言概念的实现。它们用于Java以外的其他几种语言,并且理论上可以用于编译任何语言。经过多年的非常高级的优化,Java在性能上已接近于编译语言,这表明与平台无关的高性能虚拟机技术的总体目标是可以实现的。

与您的需求相关的另一种处于早期/循环阶段的新想法称为重新计算项目,尽管可以用于其他目的,但也用于科学研究。这个想法是通过虚拟机技术使计算实验可复制。这主要是在任意硬件上模拟不同机器架构的想法。


8
Sun既没有发明虚拟机也没有发明字节码,它们甚至都不是第一个利用它们赚钱的人。查找p代码。
jmoreno

@jmoreno:他可能还想查找Smalltalk。
鲍勃·贾维斯

本文不主张sun发明的虚拟机/字节码。还有其他历史没有被引用但被提及。顺便说一句,这里非常相关的另一项关键技术:谷歌本地客户端(chrome功能)
vzn 2015年

5

高层原因

当您考虑它时,微处理器的作用惊人:它使您可以拿起一台机器(例如洗衣机或电梯),并用便宜的,批量生产的硅片来替换整块定制设计的机构或电路。芯片。您可以节省大量零件成本,并节省大量设计时间。

但是,坚持使用标准芯片替代无数的定制设计吗?不可能有一个完美的微处理器适合每个应用程序。一些应用程序需要最小化功耗,但并不需要很快。其他的则需要快速但不需要易于编程,其他的则需要低成本等。

因此,我们有许多不同的微处理器“风味”,每种都有其优点和缺点。他们希望所有人都使用兼容的指令集,因为这样可以重复使用代码,并且更容易找到具有适当技能的人员。但是,指令集确实会影响处理器的成本,复杂性,速度,易用性和物理约束,因此我们有一个折衷方案:存在一些“主流”指令集(以及许多次要指令集),以及每个指令集中有许多具有不同特性的处理器。

哦,随着技术的变化,所有这些权衡都会发生变化,因此指令集不断发展,新的指令集出现了,旧的指令集消失了。即使今天有一套“最佳”的指令集,也可能不到20年。

硬件细节

指令集中最大的设计决策可能是字长,即处理器可以“自然地”操纵多少个数字。8位处理器处理从0到255的数字,而32位处理器处理从0到4,294,967,295的数字。为一个设计的代码需要完全为另一个设计。

不仅仅是将指令从一个指令集转换为另一个指令集的问题。在不同的指令集中最好采用完全不同的方法。例如,在8位处理器上,查找表可能是理想的,而在32位处理器上,出于相同的目的,算术运算会更好。

指令集之间还有其他主要区别。大多数说明分为四类:

  • 计算(算术和逻辑)
  • 控制流
  • 数据传输
  • 处理器配置

处理器在执行哪种类型的计算以及如何处理控制流,数据传输和处理器配置方面有所不同。

例如,某些AVR处理器既不能相乘也不能相除。而所有x86处理器都可以。您可能会想到,消除乘法和除法等任务所需的电路可以使处理器更简单,更便宜。如果需要,这些操作仍然可以使用软件例程执行。

x86允许算术指令从内存中加载其操作数和/或将其结果保存到内存中;ARM是一种加载存储体系结构,因此仅具有一些专用的访问内存的指令。同时,x86具有专用的条件分支指令,而ARM几乎允许有条件地执行所有指令。同样,ARM允许将移位作为大多数算术指令的一部分进行。这些差异导致不同的性能特征,芯片内部设计和成本的差异以及汇编语言级别的编程技术的差异。

结论

不可能使用通用汇编语言的原因是,要正确地将汇编代码从一个指令集转换为另一指令集,就必须重新设计代码,这是计算机尚无法完成的。


很好的答案!人们还不太了解,我们中到处都有需要编程的计算事物。不仅仅是我们在屏幕上看到的应用程序。每年生产几百亿个芯片?
小灵通

4

DW的回答令人惊奇:如果您想要一个汇编器,则需要维护所有体系结构,在其中进行完美的翻译,并完全了解您在做什么。
每个体系结构中一些经过高度优化的代码都需要取消优化,在更抽象的层次上进行理解,然后彼此优化。
但是,如果可能的话,我们将拥有完善的C编译器,并且纯汇编形式的编写根本不会有任何好处。
使用汇编程序的要点是性能,这不能从最近的编译器中得到压缩。
编写这样的程序比现有的编译器还要难,而维护正在创建的所有新架构都将使其变得更加困难。
对于“仅一个”程序,这也意味着完全向后兼容。


在大多数情况下,gcc的优化效果要优于程序员。使用汇编程序的主要目的是完成您在C中无法完成的工作,例如访问寄存器。如果您看一下Linux源代码树,它们几乎就是汇编语言。
slebetman

@slebetman-gcc允许您将变量放入寄存器,而无需使用汇编。
Jirka Hanika

@JirkaHanika:您是在谈论使用特殊指令寻址的CPU寄存器还是专用硬件寄存器?我怀疑slebetman是指后者。
PJTraill

“所有代码”-“ GCC更好” =“您使用汇编程序”。是的,您可以访问没有汇编程序插入的寄存器。
Evil

@PJTraill-Slebetman的评论通常很好,也许应该纳入答案。但是,他的两个例子(注册访问和Linux源代码树)都可能引起普遍的误解,而不是它们是使用gcc扩展在C语言中无法完成的出色例子。那些应该被替换或省略。(如果今天有HW指令要执行某项操作,则从现在起您将有相应的gcc扩展名。并非总是如此,但经常出现。示例年龄。)
Jirka Hanika 2015年

3

Microsoft发明了MSIL作为一种中间汇编语言。程序可以从C#或VB.Net编译为MSIL。在运行时,使用JIT编译器将MSIL编译为运行它的机器的机器代码。包含MSIL的文件是一个.EXE文件,在X86开头带有一些用于启动程序的指令。在ARM处理器上,您可以在程序名称前面键入单词mono来运行它。


“中间汇编语言”和“虚拟机”有什么区别?
鲍勃·贾维斯

@BobJarvis:一个是代码,另一个是解释器。您应该已经问过中间程序集和字节码有什么区别
slebetman

这似乎无法回答问题。只要每台机器以不同的方式编译/组装MSIL,就没有通用性,并且这种编译的目的是移植通用功能,而不是利用DW指出的特定指令集(或a)使用汇编程序的原因。
PJTraill 2015年

3

如上所述,到目前为止,LLVM是最接近的东西。真正通用语言的最大障碍将是与隐式权衡有关的根本差异:并发性,内存使用,吞吐量,延迟和功耗。如果以显式SIMD样式编写,则可能会占用过多内存。如果以显式SISD样式编写,则将获得次优的并行化。如果针对吞吐量进行优化,则会损害延迟。如果最大化单线程吞吐量(即时钟速度),则会损害电池寿命。

至少,代码需要进行权衡。对于语言来说,最重要的是要具有良好的代数/类型属性,从而为编译器提供大量的摆动空间,以优化和检测逻辑上的不一致。

然后是未定义行为的问题。C语言和汇编语言的大部分速度来自未定义的行为。如果您承认实际上确实会发生未定义的行为,那么您最终会将它们作为特殊情况处理(即:体系结构和特定于上下文的黑客)。


0

也许您正在寻找的是通用车削符号,每个人都同意命令的符号。(https://en.wikipedia.org/wiki/Universal_Turing_machine

一个“汇编程序”,将“可以接受的语言”翻译成特定于供应商的基础机器代码,并为我们称为计算机的任何事物而构建。

在《计算机编程艺术》中,有一个示例可能看起来像。

但是考虑一下“为什么它们的市场通用语言不能在所有计算机上使用”这个问题,我建议最主要的影响是(1)方便,并不是所有汇编语言都最方便使用;(2)经济,提供,不同品牌的机器与供应商之间的不兼容性是一种商业策略,也是设计机器资源(时间/金钱)有限的结果。


问题是询问可用于对任何计算机编程的汇编语言,而不是“通用图灵机”意义上的通用汇编语言。
David Richerby

1
Church-Turing告诉我们UTC可以做任何可编程计算机可以做的事情。除了有限的物理存储问题。UTC的汇编语言非常可行。但是正如我所说,文化和经济实用性可能会限制市场上的实际实施和采用。
克里斯(Chris

您错过了最大的问题,那就是性能!为什么仅仅为了实现与硬件无关的崇高目标而使用慢一千倍的语言?图灵机是用于实际计算的可怕模型。
Artelius

1
评论员是否愿意提供任何计算机科学来支持其主张?毕竟这是计算机科学论坛。
克里斯(Chris

1
我不是CS专家。但是我相信冯·诺依曼体系结构是一项出色的工程,可以在可编程性和性能之间取得平衡,而图灵机的目的是表明即使最基础的机器也可以计算更复杂的机器可以进行的任何处理。当然,您可以继续向Turing机器中添加越来越多的功能(更多的磁带,算术),但是首先您遇到的是相同的问题,即人们对指令集的看法不同。另外,缺少随机访问会在许多算法中造成很大的开销。
Artelius

0

假设:将高级语言L1编译和优化为低级语言L0比将高级语言L2(高于L1)编译和优化为L0更容易;从某种意义上讲,在编译L1至L0时比生成L2至L0时,您可以生成更多优化的代码,这更容易。

我认为该假设可能是正确的,这就是为什么大多数编译器可能使用低级中间语言(IR / LLVM)的原因。

如果是这样,则使用任何低级语言L0并编写编译器以将L0转换为其他低级语言。例如,使用MIPS指令集,并将其编译为x86,arm,power,...

-陶菲克


所以您不知道您的答案是否正确?不能支持吗?
Evil
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.