assembly 如何使用汇编来判断当前的cpu类型

3j86kqsm  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(129)

既然我正在学习汇编和不同的CPU类型使用不同的功能或寄存器不同。有没有一种方法能够编码和区分ARM,英特尔或AMD处理器之间的差异?
我一直在研究,没有发现任何东西。
编辑:这个问题的目的是确定我们是否会为所有平台创建汇编代码,以及它们是否会单独基于CPU和架构运行,而不是为每个平台创建单独的构建以使其更容易。

kqlmhetl

kqlmhetl1#

要查找的关键词是“CPU检测”或“CPU识别”。
用于区分 * 体系结构 *,如ARM与Intel(x86),这个问题是没有实际意义的。在汇编级,您必须首先选择一个体系结构来决定要编写什么指令。例如,如果您想将两个数字相加,您是否编写了add eax, ebx(组装到字节01 d8),还是写add x0, x1, x2(汇编到20 00 02 8b)?在前一种情况下,您是在为x86编写代码。你必须执行很多以前的指令,这些指令只能在x86上运行,所以当你到达那里的时候,你已经知道答案了。
(从技术上讲,相同的字节序列将在两种架构上做一些事情;通常汇编器/链接器会用正确的体系结构标记你的可执行文件,如果它与运行它的机器不匹配,操作系统会拒绝执行它。)
为了区分 * 相同 * 架构的CPU,您首先必须决定是哪种架构,因为方法可能会非常不同。通常,通常会有一些特殊的指令返回有关CPU的信息。在x86上,您主要使用cpuid,在ARM 64上,有各种系统寄存器通过mrs访问,等等。对于它们如何工作,以及如何解释结果,您必须查阅该体系结构的指令集参考。
特别是对于x86,这些年来已经发布了许多不同的x86 CPU(英特尔,AMD和其他现已解散的竞争对手之间),检测可能非常复杂,这取决于你想追溯到多远。(例如,cpuid指令并不总是存在,因此区分较旧的CPU(例如2000年以前的CPU)的问题可能会填满一篇长文。还有一个额外的问题,你的程序甚至可能不在x86硬件上运行,而是可能在一个虚拟机中,使用其他一些模拟x86的CPU。
在大多数情况下,“我如何分辨哪种CPU”这样的一般性问题并不是真正应该问的问题,而是应该确定您感兴趣使用的特定CPU特性(例如AVX指令、增强型rep movsb等),然后问“我如何判断这个CPU是否支持”,那么通常会有一个简单的答案,例如,“将0x 1234加载到eax中,执行CPUID,并检查ecx的第7位”(编造的例子)。除此之外,没有必要编写大量代码来区分2035 MHz的Brandy Lake i8- 1234 U或3107 MHz的Vodka Lake i9- 9876 Z之间的区别;原则上,您可以找到您正在运行的是哪一个,但作为程序员,您没有实际的理由去关心。

相关问题