You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86_64下保留零/非零状态将64位寄存器转为32位的最优方法

可选优化方案及对比

你提出的popcntq方案已经是代码体积最小的最优解之一,还有两类针对不同优化目标的更优方案可选:

方案1:最低延迟(基础指令集,无扩展依赖)

适用场景:优先追求执行速度,可接受稍大的代码体积和临时寄存器占用

# 输入为rax,输出结果在eax
movq %rax, %rcx
shrq $32, %rcx
orl %ecx, %eax

正确性验证:将rax的高32位移到rcx的低32位,与rax原生低32位做或运算,只要原rax任意一位为1,eax就会非零,完全匹配需求。
性能参数:主流Intel平台下延迟2周期(movq支持寄存器消除,0延迟;shrq 1周期;orl 1周期),吞吐量每周期可执行2组以上,代码总大小9字节。

方案2:最高兼容性(全x86-64平台支持)

适用场景:需要兼容不支持POPCNT的老旧处理器,不需要任何扩展指令集

# 输入为rax,输出结果在eax
testq %rax, %rax
setnz %al
movzbl %al, %eax

正确性验证:testq判断rax是否为零,通过ZF标志位导出结果到8位寄存器al,再零扩展到32位eax,最终eax为0对应原rax为0,为1对应原rax非零。
性能参数:主流Intel平台下延迟2-3周期,代码总大小9字节。

原方案补充说明

你使用的popcntq方案依然是最小代码体积的最优选择:单条指令5字节,不需要额外寄存器,只要目标平台支持POPCNT扩展(2011年之后发布的Intel/AMD处理器均默认支持,对应x86-64 v2及以上规范)就可以正常使用。
注意你提到的直接读取eax的问题确实存在:当rax的高32位非零、低32位全零时(比如你举例的2^61),eax为0但原rax非零,会出现逻辑错误,不可使用。

内容的提问来源于stack exchange,提问作者Noah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:57:02