英特尔和AMD处理器有相同的汇编语言吗?

39
C语言被用来编写Unix以实现可移植性——使用不同编译器编译的相同C语言程序会产生不同的机器指令。那么为什么Windows操作系统能够在IntelAMD处理器上运行呢?

2
有人还记得 AMD 的 K5 系列吗? :) - Nick Dandoulakis
现在AMD正在开发ARM64,这个问题就有点含糊了 :-) - Jeff Hammond
1
AMD一直制造与英特尔兼容的CPU... - Yousha Aleayoub
6个回答

41
AMD和Intel处理器(*)有很多共同的指令集,因此编译器或汇编器可以编写在两者上“相同”运行的二进制代码。
然而,即使是来自同一制造商的不同处理器系列也有自己的指令集,通常被称为“扩展”或其他名称。忽略x87协处理器,我记得第一次将此作为营销点的时候是当一切突然变成了“带有MMX技术”。预期在任何处理器上运行的二进制代码需要避免使用扩展,或在使用之前检测CPU类型。

Intel的Itanium 64位架构与AMD的x86-64架构完全不同,因此一段时间内它们的64位产品是不兼容的(而且Itanium与x86完全不同,而x86-64通过添加64位指令扩展了指令集)。Intel首先选择了x86-64,尽管仍然存在一些差异:AMD64和Intel 64之间的差异

Windows可能几乎在所有代码中都使用通用的x86或x86-64指令集。如果各种驱动程序和编解码器以多个版本提供,并在CPU被查询后选择正确的版本,我不会感到惊讶。

(*) 实际上,Intel制造或曾经制造过各种类型的处理器,包括ARM(Intel的ARM处理器被称为XScale,但我认为他们已经出售了该业务)。AMD也制造其他处理器。但我们知道你指的是哪种Intel/AMD处理器 :-)


9
在内部,AMD和英特尔通常会以非常不同的方式处理这些常见指令:一些指令在一个体系结构上的执行速度可能比另一个慢得多。 - Eric Bainville
完全正确,Linux也是如此。我是一名Linux内核黑客,如果你曾经重新编译过自己的Linux内核,你会注意到你可以针对大量的CPU类型进行目标设置,当然,选择错误的类型并安装它会导致核心转储或挂起系统。这篇文章写得非常好,由onebyone撰写! - Eric
英特尔和 AMD 的 CPU 即使在常见指令上也可能有不同的行为。具体来说,在实模式下,将 EIP 运行到 0xffffffff 之后,在英特尔上会生成异常,但在 AMD 上则会静默地回绕到 0x00000000 -- 至少就我所记得的而言。 - ephemient
1
那可能被视为“那么就不要那样做”的情况。我不是汇编程序员,所以我无法想象你为什么想这样做 :-) - Steve Jessop
Marvell现在拥有XScale ARM实现。 - Joshua
显示剩余2条评论

12
AMD是与Intel兼容的。否则,它们永远不可能在市场上站稳脚跟。
它们实际上是克隆兼容的。

10

正如你所怀疑的那样,主流的英特尔和AMD处理器具有相同的指令集。

例如,Windows不会在ARMPowerPC芯片上运行,因为它在某种程度上依赖于底层的指令集。

然而,据我所知,大部分Windows是用C++编写的,这应该可以在其他架构上移植。Windows NT甚至可以在PowerPC和其他架构上运行


3
看看 Linux 内核作为一个能够在许多不同架构、甚至使用不同指令集的操作系统上运行的例子。尽管 C 代码是可移植的,但是大量汇编语言必须为每个目标进行更改。 - Nick Meyer
4
Xbox 360采用经过修改的Windows 2000内核,在PPC架构上运行。我相信Windows可能与其他操作系统一样具备可移植性,只是微软没有强烈的动力向公众提供其他版本(因为只有像两个客户那样的需求)。 - Joey
这个答案大部分是正确的,除了在SIMD指令集的情况下。当你混合3DNow!、SSE1/2/3等指令集时,事情开始分歧。但这也是为什么x86编译器通常不支持这些指令集的原因。 - hythlodayr
4
90年代中期有一种Windows版本可以运行在PowerPC、MIPS、Alpha处理器以及x86上。这些版本逐渐在NT3.1到Win2000之间消失了。可能仍然有一种版本可以在Itanium上运行。NT的编写考虑了可移植性——有一本名为Show Stopper的好书介绍了它的开发过程——但我怀疑现在不能只是简单地重建Win7,让它在PPC上运行。 - Stephen Darlington
看看FreeBSD或NetBSD内核(和用户空间),这些操作系统在许多不同的架构上运行良好。它们处理可移植性和文档编写得非常好。 - Good Person
“Windows does not run on ARM”这句话并不准确,早在很久以前,Windows CE就支持ARM了,后来自Windows Phone 8起,Windows NT也开始支持ARM。 - phuclv

8
英特尔的80x86 CPU和AMD的80x86 "大致相同",但有些事情是完全不同的(例如,虚拟机扩展-SVM vs. VT-x),而某些事情(扩展)可能支持或不支持。然而,来自同一制造商的不同CPU上也有所不同(例如,一些英特尔芯片支持AVX2,一些则不支持)。
处理这些差异的方法有多种:
- 只使用公共子集,以便相同的代码在所有80x86 CPU上运行(例如,将其视为8086芯片)。 - 使用对一系列CPU通用的功能子集,以便相同的代码在该范围内的所有80x86 CPU上运行。这非常常见(例如,“此软件需要支持64位扩展的80x86 CPU(和操作系统)”)。 - 使用安装时测试。例如,可能会有4个不同的软件副本(编译为4个不同的CPU范围),其中安装程序决定哪个副本对正在安装软件的计算机有意义。 - 使用运行时测试。例如,代码可以使用CPUID指令执行if(AVX2_is_supported()){set_function_pointers_so_AVX2_is_used();} else {set_function_pointers_so_AVX2_is_not_used();}。注意:一些编译器(如英特尔的ICC)可以自动生成执行运行时测试的代码。
这些选项并不是互斥的。例如,安装程序可能决定安装64位版本(而不是32位版本),然后64位版本可能在运行时检查支持哪些功能,并具有使用不同功能的不同代码。
还要注意,操作系统的不同部分可以分别处理。例如,一个操作系统可能有6个不同的引导加载程序、4个不同的“HAL”、4个不同的内核和3个不同的“内核模块”来支持虚拟化;其中一些东西可能会执行运行时测试,而另一些则可能不会。
几乎所有80x86汇编器都支持几乎所有扩展(来自所有CPU制造商-例如Intel、AMD、VIA、Cyrix、SiS等)。一般来说,由程序员(或编译器)确保他们只使用已知存在的东西。一些汇编器提供了使这更容易的功能(例如,NASM提供了一个CPU ...指令,以便程序员可以告诉汇编器如果看到不支持指定CPU的指令,则生成错误)。

使用第三个选项(为特定架构安装)意味着如果您将硬盘转移到具有不同架构的新计算机中,某些已安装的程序可能会出现故障,但第四个选项更具弹性。这是否使得运行时检查更受欢迎?我知道CPU预测器可能在分支上始终正确,但效率方面我讨厌不必要的“if”语句(主要是开玩笑)。 - user904963

6
AMD和Intel使用相同的指令集。
当你在AMD处理器或Intel处理器上安装Windows时,它不会在机器上“编译”代码。
我记得在大学期间有很多人对这个问题感到困惑。他们认为“设置”意味着它在你的机器上编译代码。事实并非如此。大多数(如果不是全部)Windows应用程序都以二进制形式提供给你,而不是编译代码。
至于可移植性,并不一定完全正确。虽然C语言具有高度的可移植性,但在许多情况下,针对特定操作系统或系统编写的代码只能在该系统上进行编译/执行。例如,某些Unix机器处理文件和目录的方式不同,因此可能无法完全移植。

-3
英特尔和AMD处理器有相同的汇编器吗? 汇编器将程序组装成可以在处理器上运行的形式,所以你的问题是错误的。处理器并不使用汇编器。
如果你的意思是英特尔和AMD处理器能够运行相同的汇编器?那么答案是肯定的!
所有的汇编器都是从结构化文本文件中组装其他程序的程序。Visual Basic是一个汇编器的例子。

3
汇编器技术上是一种特定类型的翻译程序,它将汇编语言翻译成机器码。汇编语言主要由与机器码指令密切对应的助记符指令组成。Visual Basic不是汇编器。 - ecm
视觉基本是汇编语言的一个示例。这通常不是指一个汇编器。通常情况下,该术语用于指代能将符号机器码(汇编语言)转化为机器码(一对一匹配,除了宏指令)的程序名称。 - Peter Mortensen
Visual Basic是汇编器的一个例子。通常情况下,这并不是指的汇编器的含义。这个名字通常是用来指代一个能够将符号机器码(汇编语言)转化为机器码(一对一,除了宏指令)的程序。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接