【发布时间】:2018-08-28 23:05:06
【问题描述】:
在 C++ 中使用扩展程序集 (asm volatile) 语法使用 btr 重置整数位的正确实现是什么?我需要在重置之前返回位中的值。
这是我的实现,这对于 16 位整数是否正确?
std::uint16_t reset(std::uint16_t& integer, std::uint32_t bit) {
auto success = false;
asm volatile("lock btrw %1, (%2); setnc %0"
: "=r"(success)
: "i"(bit), "r"(&integer)
: "memory", "flags");
return !success;
}
这个实现是否正确?我错过了任何细节吗?我对asm() 语法或x86 程序集不太熟悉。
【问题讨论】:
-
关于近距离投票,我不相信我在问为什么我的代码行为不端,而是我是否错过了任何可能使该代码在不可预见的情况下表现不佳的细节。 StackOverflow 是我在该领域获得可靠信息的唯一来源。 x86 文档不能很好地转换为此处的语法。
-
纯粹出于兴趣,您正在创建什么软件产品需要这么多(在您的情况下)深奥的操作?而且我还没有在这里投票关闭或否决你,我真的很感兴趣。
-
我个人建议不要为此使用内联汇编。我相信编译器具有您可以调用来执行此操作的内在函数。 MSVC,
-
"r"(&integer)应该成为一个输出约束。"=m"(integer)。这也将捕获您正在修改该地址处的值这一事实。然后您可以删除%2周围的括号您的编译器应该已经支持这个内在函数。 -
你应该使用
"m" (integer)而不是"r" (&integer)。它也应该是一个读写操作数,您应该删除memory约束。另请注意,i约束是编译时的,因此如果该值仅在运行时已知(但您可以使用btr r/m16, r16),它将不起作用。最后,success是一个误导性名称(并且具有误导性类型),如果您使用setc,您也可以省略否定。