我正在阅读有关指令集的文章,然后我看到了下面一行维基百科
一些支持字节码作为其 ISA 的虚拟机(例如 Smalltalk、Java 虚拟机和 Microsoft 的公共语言运行时)通过将常用代码路径的字节码转换为本机机器代码来实现这一点。
请纠正我对“指令集”以及虚拟机对其处理的整体理解:
- 基本上,处理器的内存中加载了用于处理的指令或指令集。现在处理器接收二进制输入,而二进制输入只不过是这些指令集的“二进制”表示。对吗?
- 指令集也可以称为“机器代码”或“机器语言”。对吗?
- JVM 接受 Java 字节码并生成二进制形式的“指令集”或“机器代码”或“机器语言”。因此,我可以说字节码是 JVM 的机器语言,因为 JVM 理解字节码或将字节码作为输入,并且为操作系统生成二进制形式的“机器代码”,然后操作系统进一步将这些“机器代码”转换为处理器的“机器代码”。 正确的?
- 上述问题中加粗的部分是我想要了解的主要内容之一。由于我们没有针对特定处理器的 JVM,而是针对特定操作系统的 JVM,因此我的理解是,JVM 无法为处理器生成“机器代码”,而是会为操作系统生成“机器代码”,最后操作系统会生成要由处理器执行的“机器代码”。
请确认我的理解,如果错误,请提供详细信息和/或参考,说明为什么不正确以及正确的概念是什么。
答案1
您被两个独立、相关但又相互关联的概念弄糊涂了。您所引用的引文将它们混淆了,这毫无帮助。下面是更清晰的解释:
首先,考虑一个微处理器,例如 x86 或 ARM 芯片。它可以执行内置的 ISA(指令集架构)中的指令。它假设您尝试在其上运行的代码位于正确的 ISA 中;如果您为其输入其他 ISA 的代码,则不会发生任何有用的事情。对此有各种警告和限制,如下所述,但这就是底层实际运行的方式。
现代 ISA 通常允许“虚拟化”,即软件和硬件协作创建与它们运行的真实计算机相同类型的其他“虚拟计算机”。这就是由 VMWare、Parallels 或 Hyper-V 等软件创建的“虚拟机”。维基百科将其称为“系统虚拟机”,因为它创建了整个计算机的虚拟版本。
另一种“虚拟机”是指计算机的抽象模型。它有自己的 ISA,但该 ISA 是为某些特定目的而设计的。Java 字节码和 .NET 字节码是最广泛使用的例子。没有可以直接运行此 ISA 的硬件。相反,使用 JVM 或 .NET Runtime 等软件来运行它。这通常会将专用 ISA 转换为运行该软件的计算机的实际 ISA。维基百科将其称为“进程虚拟机,因为它通常在通用操作系统下作为单个进程运行。
现在我们有足够的背景资料来查看您的陈述:
基本上,处理器的内存中加载了用于处理的指令或指令集。现在处理器接收二进制输入,而二进制输入只不过是这些指令集的“二进制”表示。对吗?
不完全是。指令集是内置处理器。处理器要运行的程序被加载到内存中,处理器从内存中取出组成程序的指令。这是以小组指令的形式发生的,而不是整个程序被吸入(除非它是非常小的)。
指令集也可以称为“机器代码”或“机器语言”。对吗?
指令集是处理器可以运行的所有指令类型以及它们的表示方式、限制等的总和。“机器代码”由遵循 ISA 规则的指令组成,已准备好供处理器运行。
JVM 接受 Java 字节码并生成“指令集”或“机器代码”或“机器语言”的二进制形式。因此,我可以说字节码是 JVM 的机器语言,因为 JVM 理解字节码或将字节码作为输入
到这里就正确了。
和为操作系统生成二进制形式的“机器代码”,然后操作系统进一步将这些“机器代码”转换为处理器的“机器代码”。正确的?
不。传统操作系统要求其程序为正确的组合OS 和 ISA,在运行程序之前不做任何翻译。(我知道有一个实验性的 OS 确实会做翻译,但它从未成为产品,也从未在其开发项目之外使用过。)
进程虚拟机(例如 JVM)是为操作系统和 ISA 的特定组合构建的传统程序。它将 Java 字节码转换为主机的 ISA,但在执行此操作时,它必须符合主机操作系统的机器代码约定。它还必须将 Java 字节码发出的输入和输出请求转换为对主机操作系统的调用。
举个例子可以让这一点更清楚:
SPARC Solaris JVM 会将 Java 字节码转换为 SPARC 指令,并将 Java i/o 转换为 Solaris i/o。
x86-64 Solaris JVM 会将 Java 字节码翻译成 x86-64 指令,并将 Java i/o 翻译成 Solaris i/o。与 SPARC Solaris JVM 相比,机器码翻译有很大不同,但 i/o 翻译非常相似。
x86-64 Windows JVM 会将 Java 字节码翻译成 x86-64 指令,并将 Java i/o 翻译成 Windows i/o。与 x86-64 Solaris JVM 相比,机器码翻译非常相似(尽管有些约定不同),但 i/o 翻译却大不相同。
因为我们没有针对特定处理器的 JVM,所以我们有针对特定操作系统的 JVM,所以我的理解是 JVM 不能为处理器生成“机器代码”,而是会为操作系统生成“机器代码”,然后最终操作系统会生成要由处理器执行的“机器代码”。
恐怕这是完全错误的。见上文。
注意事项和资格
通过切换到不同的“模式”,许多处理器能够执行多个指令集。现代 x86 处理器至少有三种模式:16 位(现在很少使用)、32 位和 64 位。ARM 处理器有多种模式,可从 ARM 32、Thumb 32 和 ARM64 中选择。
大多数操作系统的编程工具都会在程序开头添加信息,标明程序所需的 ISA。这样操作系统就可以在尝试运行程序之前检查程序是否适合运行。
有些处理器有“微代码”,即告诉处理器如何运行特定指令的软件。它不在主内存中,而是在处理器内部的特殊存储器中。