- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 x86 上的 64 位模式下,大多数 32 位算术运算会清除目标寄存器的前 32 位。如果算术运算是“cmov”指令,并且条件为假怎么办? (我看过的引用手册好像都没有这个案例)。
最佳答案
它总是零扩展到目的地,就像所有写入 32 位寄存器的指令一样。
将 CMOV 视为总是写入其目的地:它是一个 ALU 选择操作(3 个输入:2 个整数操作数和标志,1 个输出)。
它不像 ARM 32 位模式谓词指令那样在条件为假时真正像 NOP。
(出于同样的原因,cmovcc reg, [mem]
always loads the memory operand ,即使条件为假,也不会对错误地址进行故障抑制。同样,它不是移动本身是有条件的,它正在移动条件选择操作的结果。AArch64 为其等效的相同指令选择了一个更好的名称,csel
。)
在一种情况下,32 位目标可能不会被零扩展:bsr
和 bsf r32,r/m32
当源为零时,目标保持不变。 (仅记录了 by AMD(如果第二个操作数包含 0,则指令设置 ZF为 1 并且不会更改目标寄存器的内容。),但也由 Intel 实现)。至少在 Intel CPU 上的实践中,这包括在像 bsf eax, ecx
这样的指令之后不修改高位。我没有测试过 AMD。
(这就是 BSF 和 BSR 对目的地具有“假”依赖性的原因:无分支地实现此行为需要真正的依赖性。只有 a false output dependency for LZCNT/TZCNT/POPCNT on Intel 在同一执行单元上运行但始终会覆盖它。)
( Wikipedia ) 声称在 bsf r32, r/m32
之后的高位在 Intel 和 AMD 之间存在某种差异。他们似乎在说英特尔(或者可能是 AMD;措辞有些含糊)在 source=0 的情况下保留高位 未定义,而不是未修改。
在我对 Sandybridge 系列和 Core 2 的测试中,它似乎始终未修改,但我无法访问 P4 Nocona/Prescott,这是第一代 IA-32e 微架构。
撰写这篇文章的维基百科编辑可能只是误解了英特尔的文档,该文档称在这种情况下整个目标寄存器是“未定义的”。 (但它是 normal for Intel to, in silicon, go beyond what they guarantee on paper ,所以他们关心的现有软件,例如 Windows,继续工作)。 IDK 如果该声明还有其他来源,那么我想 [citation-needed] 在这里真的很合适。
关于assembly - 在 x86_64 中,如果条件为假,32 位 cmov 是否会清除最高位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66416287/
我在某处看到 GCC 编译器在将我的代码转换为 ASM 时有时可能不喜欢使用条件 mov。 在哪些情况下它可能会选择执行条件 mov 以外的操作? 最佳答案 当分支的两边都很短时,编译器通常倾向于将
我似乎无法得到 cmove以我想要的方式工作。我有这么一段代码: cmove $1, %eax 我在编译时收到此错误: Error: operand type mismatch for `cmov
这个问题已经有答案了: Why is a conditional move not vulnerable to Branch Prediction Failure? (5 个回答) 已关闭 7 年前。
C 代码: int cread(int *xp) { return (xp ? *xp : 0); } 汇编代码:(来自不允许编译器执行的教科书示例)使用条件移动指令 movl $0,
我正在尝试编写一些高性能汇编函数作为练习,并且在运行程序时遇到了一个奇怪的段错误,但在 valgrind 或 nemiver 中没有。 基本上不应该运行的 cmov,带有越界地址,即使条件始终为假,也
对于 64 位寄存器,有 CMOVcc A, B指令,只写 B至 A如果条件cc满意: ; Do rax <- rdx iff rcx == 0 test rcx, rcx cmove rax, rd
我知道当一个分支很容易预测时,最好使用 IF 语句,因为该分支是完全免费的。我了解到,如果分支不容易预测,那么 CMOV 会更好。但是,我不太明白如何实现这一点? 当然,问题域仍然是相同的——我们不知
为了在运行 Windows 7 pro 的英特尔核心 2 上执行一些 cmov 指令,我编写了下面的代码。它所做的只是从控制台获取一个字符串作为输入,应用一些移位操作来生成一个随机种子,然后将该种子传
我有一个由一个生产者写入并由 N 个消费者读取的环形缓冲区。因为它是一个环形缓冲区,所以生产者写入的索引小于消费者当前的最小索引是可以的。生产者和消费者的位置由他们自己的 Cursor 跟踪。 cla
我有这个简单的二进制搜索成员函数,其中 lastIndex 、 nIter 和 xi 是类成员: uint32 scalar(float z) const { uint32 lo = 0;
在 x86 上的 64 位模式下,大多数 32 位算术运算会清除目标寄存器的前 32 位。如果算术运算是“cmov”指令,并且条件为假怎么办? (我看过的引用手册好像都没有这个案例)。 最佳答案 它总
文章中Linear vs. Binary Search ,有一个使用 CMOV 指令的二进制搜索的快速实现。我想在 VC++ 中实现它,因为我正在处理的应用程序依赖于二进制搜索的性能。 该实现有一些
我正在尝试使用内部汇编器在 V8 中实现我自己的 Math.clamp 版本。 我设法使用 Torque 脚本语言生成了它的一个版本,并想尝试使用 CodeStubAssembler 内置函数进行类似
我是一名优秀的程序员,十分优秀!