实时编译器(JIT)
是否真的将程序中的每个公共中间语言(CIL)
指令映射到底层处理器的opcodes
?
如果是这样,我们可以称CIL为汇编语言,JIT为汇编程序吗
注:维基百科在其汇编语言列表
中没有将CIL列为汇编语言。这个问题都是关于定义的,所以让我们正确定义术语。第一,汇编语言:
汇编语言是一种用于计算机、微处理器、微控制器和其他可编程设备的低级编程语言,其中每条语句对应于一条机器语言指令。汇编语言是特定于特定计算机体系结构的,而大多数高级编程语言通常可移植到多个系统。
现在,CIL:
通用中间语言是由通用语言基础结构(CLI)规范定义的最低级别的可读编程语言,由.NET Framework和Mono使用。以CLI兼容的运行时环境为目标的语言编译为CIL,CIL被汇编成具有字节码样式格式的对象代码。
好吧,这部分在技术上是不正确的:例如,C#编译器直接编译到字节码,它不经过CIL(人类可读语言),但理论上,我们可以想象这就是发生的事情。
有了这两个定义,CIL就是汇编语言,因为其中的每条语句都被编译为一条字节码指令。事实上,没有一台物理计算机可以直接执行字节码,这并不重要。
该定义称,每种汇编语言都"特定于特定的计算机体系结构"。在这种情况下,体系结构是CLR虚拟机。
关于JIT:JIT编译器不能被视为汇编程序:它不进行从人类可读形式到字节码的1:1转换,ilasm
做到了。
JIT编译器是一个优化编译器,它在进行优化的同时,将字节码编译为本机代码(无论运行在哪个ISA/CPU上)。
程序集由特定处理器的机器代码指令的助记符组成。1和0的直接表示,使核心执行代码,但用文本编写,使其在人类身上更容易。这与CIL:非常不同
- 你买不到执行CIL的处理器
- CIL不针对特定的处理器,抖动会
- CIL假设基于堆栈的执行模型,处理器主要基于寄存器
- CIL代码从其原始形式进行了优化
- 不存在CIL指令到处理器指令的一对一转换
最后一点是关键,使CIL与字节码有很大不同的设计决策是CIL指令是无类型的。只有一条ADD指令,但处理器有很多版本。特定的ADD指令采用字节、短、int、长、浮点和双操作数。必需,因为处理器核心的不同部分用于执行添加。抖动根据它从以前的CIL指令中推断出的操作数类型,选择正确的一个。
就像C#语言中的+运算符一样,它也可以处理不同的操作数类型。这确实使CIL中的L意义重大,它是一种语言。一个简单的例子,但它只是简单地帮助它轻松地写抖动。
这条线实际上很模糊。。。我看到的反对将CIL
称为"汇编语言"的论点在实践中几乎同样适用于x86
/x86-64
。
英特尔和AMD还没有制造出几十年来(如果有的话)完全执行汇编指令的处理器,因此即使是所谓的"本机"代码也与在字节码由x86
/x86-64
指定的虚拟机上运行没有太大区别。
x86
/x86-64
是典型开发人员可以访问的最低级别的东西,所以如果我们必须脚踏实地,将生态系统中的某些东西称为"汇编语言",那将是胜利的,而且由于CIL
字节码最终需要x86
/x86-64
指令才能在该系列的处理器上运行,然后有一个非常有力的理由可以证明,它确实"感觉"不应该算数。
因此,在某种意义上,两者都不能被视为"汇编语言"。当提到x86
/x86-64
处理器时,我们几乎从来没有提到执行x86
/x86-64
而不将其转换为其他内容(即,无论微码做什么)的处理器。
为了增加另一个问题,x86
/x86-64
处理器执行给定指令序列的方式可以简单地通过更新微码来改变。快速搜索显示,Linux甚至可以让你自己在软件中轻松做到这一点!
所以我想,这里有一些标准可以证明将它们分为两个不同的类别:
- 当前所有运行
CIL
字节码的机器都在软件中实现,这有关系吗 - 在软件中指示相同的硬件可以以不同的方式解释相同的
x86
/x86-64
指令,这有关系吗 - 我们目前没有绕过微码并直接向
x86
/x86-64
处理器的物理单元发出命令的方法,这有关系吗
因此,关于"CIL
是汇编语言吗"的问题,我能给出的最好答案是"取决于"(对于科学家)和"几乎"(对于工程师)
MSIL JIT是该字节码的虚拟机的实现。实现(来自微软或Mono)如何将CIL转换为机器代码,这是一个实现细节,对你来说并不重要(而且考虑到微软虚拟机可能是专有的,所以不会告诉你它是如何实现的)。我认为Mono是CIL的一个免费软件实现,它使用LLVM,所以可能不会一次翻译每个字节码,而是可能翻译整个方法或函数。