gpt4 book ai didi

assembly - 为什么 TZCNT 适用于我的 Sandy Bridge 处理器?

转载 作者:行者123 更新时间:2023-12-04 19:30:34 26 4
gpt4 key购买 nike

我正在运行 Core i7 3930k,它属于 Sandy Bridge 微架构。
执行以下代码(在MSVC19、VS2015下编译)时,结果让我很惊讶(见评论):

int wmain(int argc, wchar_t* argv[])
{
uint64_t r = 0b1110'0000'0000'0000ULL;
uint64_t tzcnt = _tzcnt_u64(r);
cout << tzcnt << endl; // prints 13

int info[4]{};
__cpuidex(info, 7, 0);
int ebx = info[1];
cout << bitset<32>(ebx) << endl; // prints 32 zeros (including the bmi1 bit)

return 0;
}

拆机显示 tzcnt指令确实是从内在发出的:
    uint64_t r = 0b1110'0000'0000'0000ULL;
00007FF64B44877F 48 C7 45 08 00 E0 00 00 mov qword ptr [r],0E000h
uint64_t tzcnt = _tzcnt_u64(r);
00007FF64B448787 F3 48 0F BC 45 08 tzcnt rax,qword ptr [r]
00007FF64B44878D 48 89 45 28 mov qword ptr [tzcnt],rax

为什么我没有收到 #UD操作码无效异常,指令正常运行,CPU报告不支持上述指令?

这可能是一些奇怪的微代码修订版,其中包含指令的实现但不报告对它的支持(以及其他包含在 bmi1 中的)?

我还没有检查其余的 bmi1说明,但我想知道这是一种多么普遍的现象。

最佳答案

Sandy Bridge(及更早版本)处理器似乎支持 lzcnt 的原因和 tzcnt是两个指令都具有向后兼容的编码。

lzcnt eax,eax  = rep bsr eax,eax
tzcnt eax,eax = rep bsf eax,eax

在较旧的处理器上 rep前缀被简单地忽略。

好消息就这么多。
坏消息是两个版本的语义不同。
lzcnt eax,zero => eax = 32, CF=1, ZF=0  
bsr eax,zero => eax = undefined, ZF=1
lzcnt eax,0xFFFFFFFF => eax=0, CF=0, ZF=1 //dest=number of msb leading zeros
bsr eax,0xFFFFFFFF => eax=31, ZF=0 //dest = bit index of highest set bit


tzcnt eax,zero => eax = 32, CF=1, ZF=0
bsf eax,zero => eax = undefined, ZF=1
tzcnt eax,0xFFFFFFFF => eax=0, CF=0, ZF=1 //dest=number of lsb trailing zeros
bsf eax,0xFFFFFFFF => eax=0, ZF=0 //dest = bit index of lowest set bit

至少 bsftzcnt当 source <> 0 时生成相同的输出。 bsrlzcnt不同意。
还有 lzcnttzcnt执行速度比 bsr 快得多/ bsf .
真是糟透了 bsftzcnt不能就标志的用法达成一致。
这种不必要的不​​一致意味着我不能使用 tzcnt作为 bsf 的替代品除非我可以确定它的来源非零。

关于assembly - 为什么 TZCNT 适用于我的 Sandy Bridge 处理器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43880227/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com