ARM 的 RISC 指令集是 x86 的子集吗?如果是这样,那为什么 x86 运行 ARM 软件不能原生呢?

Is ARM’s RISC instruction set a subset of x86? If so, why can’t x86 run ARM software natively then?

根据我对指令集的有限理解,ARM 是一个 RISC 架构,这意味着比基于 x86 的处理器有显着 fewer/simpler 的指令。如果是这样的话,我希望 ARM 的指令集是 x86 指令的子集,因为我也听说过“x86 指令可以做 ARM 可以做的所有事情,甚至更多。”

如果真是这样,x86 不应该能够 运行 ARM 软件吗,因为 x86 拥有所有必要的指令?

不,不是。与 x86 指令集相比,ARM 指令集可能更受限制,但这与处理器的体系结构无关。 ARM 指令集不是 x86 指令的子集。它们的编码方式不同,处理器以不同的方式执行它们。寄存器不一样,甚至指令指针的工作方式也不一样。

因此:两种架构上的指令都不同,仅仅因为 ARM 的指令较少并不意味着 ARM 处理器支持的指令是英特尔支持的指令的子集。 除了编码之类的指令之外,还有更多的兼容性。 您既不能 运行 x86 上的 ARM 软件,也不能 assemble 将程序集武装到 x86。

不,ARM 和 x86 具有完全不同的 machine-code 格式,并且在 asm 源代码级别也不兼容。完全没有。

1,2,3 是一个比 11,12,13,14,15,16,17 小的集合,但它不是子集,所以你的类推是不成立的。以不同的方式做同样的事情意味着为 ARM 编译 high-level 代码与为 x86 编译相似,而不是它们兼容。

x86 使用长度从 1 到 15 个字节不等的指令。 ARM 使用 fixed-length(4 字节),或者在拇指模式下使用 2 或 4 字节指令。即使你碰巧有一个 2 字节的 x86 add eax, ecx 和一个 Thumb 模式的 ARM 2 字节 adds r0, r1,编码也会不同。


此外,将 RISC 视为更像是简化的 Instruction-Set 复杂性 - 每条指令必须足够简单才能通过流水线并在一个执行单元中执行(例如,将它发送到 ALU,或者加载或存储单元),但是可能有很多不同的可能指令。当然,用于乘法或除法的 ALU 不能在单个周期内完成,因此执行单元可能是流水线的。

即便如此,ARM 也不是很危险;它以增加代码密度和性能的方式偏离 RISC 哲学,例如push {r4, r5, lr, pc} 进行 4 次推送,对要推送到位图中的寄存器进行编码。这与存储单元中可变数量的内部操作有关。或者 pop 多个寄存器必须写入可变数量的寄存器,以及进行可变数量的加载。所以它不那么容易流水线(并且为了支持 load/store 对而放弃了 AArch64),但仍然不是太糟糕,特别是对于 ISA 设计的早期简单 ARM 流水线。

此外,借助 NEON SIMD 和各种其他 instruction-set 扩展,以及紧凑的 Thumb2 编码,ARM 有很多指令。


也相关: 更详细地探讨了为什么你不能在通用 back-end 前面轻拍 ARM 和 x86 front-ends 并从每个中获得良好的性能.例如不同的 memory-ordering 规则,以及 FLAGS 处理的不同怪癖,因此在每个重要的情况下,您都必须在 back-end 中处理两全其美的情况。

它们与 x86 和 mips、mips 和 risc、pdp11 和 x86 等没有任何关系

处理器非常笨,只做基本运算,read/write (store/load) 一些 alu 函数,加、减等一些逻辑运算 xor、or、and 等

CISC 在当时很有意义,而且内存相对昂贵得多,因此具有更多步骤的指令也很有意义,那时他们并没有像我们现在这样的处理器方面的丰富经验。随着事情的发展,RISC 变得更有意义,更高的整体性能,因为更少的开销(当比较我们仍在等待的苹果时),更少的功率,更少的逻辑来执行相同的任务,等等。更大的二进制文件可能是,但由于并非真正需要 cisc 指令的每一部分,因此需要权衡取舍。 x86 基本上是一个 8 位指令集,而 arm 是 32/16,那里的二进制文件会更大。所以这是对尺寸的权衡,但具有对齐的性能优势。

这有点像说,因为半挂卡车有发动机、轮胎和座椅,所以本田思域是半挂卡车的子集,因为它们具有相似的零件并且可以在相同的道路上行驶。

pdp11 可以 运行 unix,然后是 x86,这是否意味着 x86 是 pdp11 的子集?不 源自 pdp11?没有。真正的英特尔最终收购了DEC就是这样。