X64 指令在不同 CPU 上表现不同

2023-12-13

在一次采访中,我被问到是否知道 x64 指令的行为取决于所使用的 CPU,我在任何地方都找不到任何相关文档,有谁知道这些指令是什么以及为什么会出现这种情况?


有一些留下一个寄存器或一些带有未定义值的标志。英特尔和AMD 在这方面可能有所不同。

在某些情况下,真实硬件在这些未定义情况下的实际行为保留了对依赖它的某些旧软件的向后兼容性。例如,BSF输入 = 0 设置 ZF 并保持目标寄存器不变。 (在当前的 Intel 和 AMD 硬件上。我不知道旧的英特尔硬件是否有所不同,如果没有,bsf/bsr这并不是一个真正的指令示例executes不同的是,只是缺乏面向未来的书面保证.)

但不同之处在于,英特尔将其记录为让目标寄存器留下“未定义”的内容。AMD 的手册明确记录并保证 AMD CPU 将离开目的地未修改的在这种情况下。

AMD 的 AMD64 手册 (2017年3月) for bsr/bsf:
如果第二个操作数包含 0,则指令将 ZF 设置为 1,并且不更改目标寄存器的内容

所以这不是保证在纸面上,模拟 tzcnt / 实现是安全的std::countr_zero as mov eax, 32 / bsf eax, edx,尽管这在实践中有效,并且可能会继续在未来的 CPU 上发挥作用。 (这就是为什么bsf / bsr具有输出依赖性。)英特尔最终可能会记录此行为,在这种情况下,编译器将能够使用它来更有效地countr_zero / countl_zero没有 BMI1。 Intel 最近确实记录了 AVX 暗示 16 字节对齐加载/存储在 Intel CPU 上是原子的,因此供应商记录其 CPU 多年来一直在做的事情并不是史无前例的。

如果性能差异很重要,那么有很多(请参阅x86标签维基)!


您不仅仅是在谈论不受支持的指令,是吗?就像某些非常早期的 x86-64 CPU 上的长模式不支持 LAHF/SAHF 一样?或者早期 K8 也不支持 CMPXCHG16B。

不支持的指令最有趣的情况是LZCNT解码为BSR在不支持它的 CPU 上,REP 前缀将被忽略。即使对于非零输入,它们也会返回相反的结果。 (_lzcnt_u32(x) == 31-bsr(x))。 TZCNT 在不支持它的 CPU 上类似地解码为 (REP) BSF,但它们执行相同的操作,除非输入 = 0。我之前没有提到这一点,因为以不同方式运行相同的机器代码与运行相同的机器代码不同操作说明不同地,但听起来这正是您所要求的。

我们只讨论非特权指令吗?特权指令的行为可能还有更多差异。例如,Intel 和 AMD 在 SYSRET 中都有不同的错误Linux 必须解决这个问题以避免恶意用户空间导致内核挂起。


另一种情况我不确定是否有效:预取W作为 NOP 在至少从 Core2 到 Haswell 的 Intel CPU 上运行,但在 AMD CPU 上运行(以及自 Broadwell 以来的 Intel CPU)作为实际的预取.

因此,有些 CPU 将其作为 NOP 运行,有些将其作为预取运行(因此无论哪种方式都没有架构上可见的影响),除了在古老的 CPU 上,它会作为非法 insn 出错。 64位Windows8.1显然要求 PREFETCHW 可以无故障地运行(这会阻止它在(某些?)64 位 Pentium4 CPU 上运行)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

X64 指令在不同 CPU 上表现不同 的相关文章

  • 当非特权用户运行 C/asm 程序时,会对 Linux 造成什么危害?

    我一直在考虑一种场景 让用户 可以是任何人 可能有恶意 提交在 Linux PC 我们称之为基准节点 上运行的代码 目标是为单线程例程创建一种自动化基准测试环境 假设一个网站向代理发布了一些代码 该代理将此代码交给基准节点 而基准节点仅与代
  • x86-64 Linux 中不再允许使用 32 位绝对地址?

    64 位 Linux 默认使用小内存模型 将所有代码和静态数据置于 2GB 地址限制以下 这确保您可以使用 32 位绝对地址 旧版本的 gcc 对静态数组使用 32 位绝对地址 以便节省相对地址计算的额外指令 然而 这不再有效 如果我尝试在
  • 推送 64 位 intel osx

    我想将 64 位地址压入堆栈 如下所示 asm pushq 0x1122334455667788 但我得到编译错误 我只能按以下方式推送 asm pushq 0x11223344 有人可以帮助我理解我的错误吗 我是装配新手 所以如果我的问题
  • 如何获取 VESA BIOS 信息

    我正在跟踪Phil Opp 教程 https os phil opp com 关于用 Rust 编写一个操作系统 在稍微尝试了一下之后 我想在屏幕上显示真实的图形 我发现我应该从使用带有 VESA 的线性帧缓冲区开始 我在 osdev or
  • 为什么当设置为 TLS 选择器时,ES 和 DS 在 64 位内核上最终会归零?

    下面的 32 位程序调用set thread area 2 http linux die net man 2 set thread area在 GDT 中创建一个条目 该条目旨在用于 TLS 通常将结果选择器放入FS or GS并成功使用
  • 在汇编中显示两位数? [复制]

    这个问题在这里已经有答案了 我对汇编编程完全陌生 在课堂作业的示例中 需要将两个数字相加并显示总和 我发现神秘的是当其是两位数时显示总和 这是我的代码 mov al num1 mov bl num2 add al bl add ax 303
  • 编写 AMD64 SysV 程序集时使用哪些寄存器作为临时寄存器?

    我正在使用实现一个功能cpuid根据 AMD64 SysV ABI 进行组装 我需要在函数本身中使用 2 个临时寄存器 第一个用于累积返回值 第二个用作计数器 我的功能目前如下所示 zero argument function some c
  • 在 REP MOVSW 之前 PUSH CS / POP DS 的目的是什么?

    为什么在下面的代码中我们压入代码段 PUSH CS 然后将其弹出到数据段 POP DS 我将这些行明确指定为 line1 和 line2 请告诉我 MOVSW 在这里是如何工作的 IF HIGHMEMORY PUSH DS MOV BX D
  • 破坏/分解函数的函数

    我以前有过 here https stackoverflow com questions 4920610 c class function in assembly 已经表明 C 函数不容易用汇编表示 现在我有兴趣以一种或另一种方式阅读它们
  • 一条指令可以同时处于两种寻址模式吗?

    我在书中读到了以下内容从头开始编程 处理器有多种不同的访问数据的方式 称为 寻址模式 最简单的模式是立即模式 其中 要访问的数据嵌入在指令本身中 例如 如果我们想将寄存器初始化为 0 而不是给出 计算机要从中读取 0 的地址 我们将指定立即
  • C++ 中的 CPUID 实现

    我想知道这里是否有人有一些可以从任何托管 net 语言引用的 C CPUID 实现的好示例 另外 如果情况并非如此 我是否应该注意 X86 和 X64 之间的某些实现差异 我想使用 CPUID 来获取运行我的软件的机器上的信息 崩溃报告等
  • 这段汇编语言代码是什么意思?

    我是一名学生 刚刚开始学习汇编语言 为了更好地理解它 我只是用 C 写了一个简短的代码并将其转换为汇编语言 奇怪的是我有点听不懂 代码是 include
  • 在 x86 程序集中将整数打印到控制台

    当我在 16 位汇编中添加两个值时 将结果打印到控制台的最佳方法是什么 目前我有这个代码 CODE START mov ax 1 put 1 into ax add ax 2 add 2 to ax current value mov ah
  • 将两个 32 位整数向量相乘,生成 32 位结果元素向量

    将每个 32 位条目乘以 2 的最佳方法是什么 mm256i互相注册 mm256 mul epu32不是我正在寻找的 因为它产生 64 位输出 我想要每个 32 位输入元素都有一个 32 位结果 而且 我确信两个 32 位值的乘法不会溢出
  • 为什么 Solaris 汇编器生成的机器代码与 GNU 汇编器在这里不同?

    我为 amd64 编写了这个小汇编文件 对于这个问题来说 代码的作用并不重要 globl fib fib mov edi ecx xor eax eax jrcxz 1f lea 1 rax ebx 0 add rbx rax xchg r
  • Visual Studio 2017 上的简单装配程序

    386 model flat c stack 100h printf PROTO arg1 Ptr Byte data msg1 byte Hello World 0Ah 0 code main proc INVOKE printf ADD
  • 汇编基础知识:输出寄存器值

    我刚刚开始学习汇编语言 我已经陷入了 在屏幕上显示存储在寄存器中的十进制值 的部分 我使用 emu8086 任何帮助将不胜感激 model small Specifies the memory model used for program
  • 减法进位标志

    我正在使用 MASM32 有了这个代码 mov eax 5 sub eax 10 CF 状态标志将被设置 但使用我的铅笔和纸 我实际上看到 MSB 没有任何进位 是的 我知道从较少的数字中减去大的数字集CF 但我想知道为什么 因为使用这段代
  • 为什么 RISC-V S-B 和 U-J 指令类型以这种方式编码?

    我正在读一本书 计算机组织与设计RISC V版 我遇到了 S B 和 U J 指令类型的编码 我上面提到的那些类型有奇怪的编码立即字段 S B 类型将直接字段分为两部分 这是有道理的 因为所有指令编码都必须相似 但我无法理解为什么立即字段以
  • 从汇编程序获取命令行参数

    通读 专业汇编语言书籍 似乎它提供了用于读取命令行参数的错误代码 我纠正了一点 现在它从段错误变成了读取参数计数 然后是段错误 这是完整的代码 data output1 asciz There are d params n output2

随机推荐

  • 从文本中获取CGPath

    海吉同志们 我目前正在尝试将一个字母和 或多个字母转换为 CGPathRef 以便手动将它们绘制到自定义 UIView 中 我尝试了 CoreText 和 Framesetters 的方法 包括这个小片段 但它似乎不起作用 NSAttrib
  • 如何从 subprocess.communicate() 捕获 python 中的流输出

    目前 我有这样的事情 self process subprocess Popen self cmd stdout subprocess PIPE out err self process communicate 我正在运行的命令会流式传输输
  • 自动完成查找字符串包含的符号而不是开头的符号

    我正在编写一个程序 该程序在某一时刻实现了TextBox具有自动完成功能 目前 为了简单起见 我正在使用CustomSource在设计时手动填充多个条目 虽然自动完成工作正常 但我希望它提出的建议不仅仅是从 开始当前输入的文本 但是包含它在
  • Python在Words文档中查找替换字符串并在字符串之前创建两个段落

    我有一个 VBA 宏 在那方面 我有 Find Text Pollution Replacement Text p pChemical Here p pChemical 表示将 污染 一词替换为 化学 并在 海洋 一词之前创建两个空段落 B
  • 通过隐藏字段内的 ID 删除表行

    我有一个表 它在 JSP 中的 while 循环中生成其行 如下所示 我在每行中使用隐藏字段来获取特定 ID 并将其 POST 到 servlet tr td td tr
  • 优点、问题、向 iOS 应用程序添加另一个 UIWindow 的示例?

    最近我一直想知道 iOS 应用程序只有一个UIWindow 创建另一个似乎不是问题UIWindow并将其放置在屏幕上 我的问题有点模糊 但我感兴趣的是 第二次我可以实现什么目标UIWindow不能用其他方式做到吗 使用多个时可能会出现什么问
  • 使用 NEST 的 Elasticsearch:如何配置分析器来查找部分单词?

    我试图按部分单词进行搜索 忽略大小写并忽略某些字母的重音 是否可以 我认为带有默认分词器的 ngram 应该可以解决问题 但我不明白如何使用 NEST 来做到这一点 示例 musiic 应匹配包含 music 的记录 我使用的Elastic
  • 在VBA过程中使用ADODB查询Excel文件时,多个JOIN不可用吗?

    我有 3 张数据表 数据格式为表格 工作表名称为 Riesgos Eventos 和 Eventos Riesgos EventosRiesgo 拥有与事件和风险相关的信息 多对多关系 我试图获取来自 Riesgos 的所有风险 以及与来自
  • 如何在 TFS 构建中获取 nuget 恢复

    我无法让它工作 TFS 构建 这是 nuget 恢复问题 Nuget 不恢复引用 dll 文件 下面是我的构建配置 请告诉我如何才能使其发挥作用 As per 这篇博文在 Nuget 的网站上 您可以使用您提到的命令行 但它必须是使用Bui
  • 在 bash 中按特定顺序打印文件

    我有包含内容的文件 文件 txt Iteration 1 RAM 456ms Cache 142ms total 417ms Iteration 2 Spec 152ms Cache 149ms total 413ms Iteration
  • 调整字体大小后 Webview 高度不改变

    在我的应用程序中 我使用 ScrollView 这个ScrollView包含了很多Webview 我更改网络视图字体大小 webView getSettings setTextSize WebSettings TextSize LARGER
  • 使用 PKCS#8 编码的私钥创建兼容的 Java“RSA”签名

    我有 pkcs8 rsa private key 文件 它是由 openssl 从 rsa private key pem 文件生成的 我需要在python中通过私钥进行签名 使用下面的java代码进行相同的签名 public static
  • 面积图中的颜色变化

    我有一个扩展 AreaChart 的 Java 类 我想实现一种方法 或多或少是这样的 public void addNewColorToData xCoordinate yCoordinate redColor greenColor bl
  • 如何在普通 Python 3 中监听原始以太网帧?

    我正在用 Python 进行一些自学的低级网络编程 我在用着乌班图18 04 and Python 3 使用此代码 我可以发送原始以太网数据包 from socket import socket as Socket AF PACKET SO
  • 查找文本节点

    是否有一个聪明的 jQuery 选择器来选择这样的文本节点 div div
  • 如何从命令行获取正确的 Windows 版本

    如何从命令行 包括 PowerShell 获取正确的 Windows 版本 正如我尝试过的所有解决方案 答案如何从 PowerShell 命令行查找 Windows 版本 但现在没有人能够给出这个 您可以从注册表中检索它 gt e g 22
  • Java持久化API中FetchType LAZY和EAGER的区别?

    有什么区别FetchType LAZY and FetchType EAGER在 Java 持久性 API 中 有时您有两个实体 并且它们之间存在关系 例如 您可能有一个名为University另一个实体称为Student一所大学可能有很多
  • 如何在 Flutter 中使用 BottomNavigationBar 维护 Webview 状态

    我正在创建一个 Flutter 应用程序 它使用 BottomNavigationBar 在页面之间进行更改 在其中一个页面中 我有一个 Webview 我正在使用plugin由 Flutter 开发团队开发 当我导航到另一个选项卡然后返回
  • 这是创建审计跟踪的最佳方法吗?

    我正在尝试创建一些功能 以保留给定用户表单中的数据如何随时间变化的审计跟踪 并在该页面的底部提供带日期的审计 例如 02 04 09 21 49 名称从 Tom 更改为 Chris 我这样做的方法是将数据以其当前格式存储在会话中 然后在保存
  • X64 指令在不同 CPU 上表现不同

    在一次采访中 我被问到是否知道 x64 指令的行为取决于所使用的 CPU 我在任何地方都找不到任何相关文档 有谁知道这些指令是什么以及为什么会出现这种情况 有一些留下一个寄存器或一些带有未定义值的标志 英特尔和AMD 在这方面可能有所不同