【问题标题】:Instruction encoding for atomic increment of a long variable长变量原子增量的指令编码
【发布时间】:2014-08-10 06:07:37
【问题描述】:

我需要为长变量的原子增量获取指令编码。我正在考虑编写一些内联 gcc 程序集并使用 gdb 反汇编输出来获得答案。这就是我所做的。

#include <stdint.h>

int lock_inc(uint64_t *value) {

  __asm__ __volatile__
  (
   "lock inc %0;\n"
   :
   : "r"(value)
   : "memory"
  );
}

uint64_t value = 0;

int main() {

  lock_inc(&value);

}

但是当我尝试编译它时,我得到了以下错误。

lockinc.c:汇编程序消息:lockinc.c:5:错误:期望可锁定 `lock' 后的指令

我做错了什么?顺便说一句,如果有人知道直接答案(编码),那也很好。 (我指的是一些网站直接获取它,但不确定答案。感觉让 gcc 做会更容易。)

【问题讨论】:

  • 您的使用说明书是怎么说的?我认为您不会在没有随时打开手册并准备好进行咨询的情况下进行此类工作。
  • 中肯的建议。 :)。我想我是想找到简单的出路。
  • 一个不需要 asm 的“怎么做”问题:stackoverflow.com/questions/2353371/how-to-do-an-atomic-increment-and-fetch-in-c

标签: gcc assembly x86-64 atomic inline-assembly


【解决方案1】:

您不能对寄存器使用锁定。您必须使用“m”作为约束,而不是“r”。此外,由于您既要阅读又要写作,因此“值”应该是标有“+”的输出。为什么不直接使用 __sync_add_and_fetch?

【讨论】:

  • 得到它的工作与您的建议。谢谢。我不能使用 __sync_add_and_fetch 因为这段代码需要在运行时生成然后执行。顺便说一句,答案是“f0 48 ff 05 0a 04 20 00”,在我的情况下,它转换为“lock incq 0x20040a(%rip)”,其中 f0 是 LOCK 前缀,48 是 REX 前缀,ff 是 incq 的操作码。
  • @chamibuddhika 在代码示例/答案中嵌入诸如0x20040a 之类的魔术常数是......很少是实际(正确)答案。特别是如果您谈论的是生成的代码。根据该代码块在内存中的位置,“魔法”将会改变。更好的东西,精灵回到瓶子里;-)
  • 真 :)。但我的要求是使用锁定和所需前缀对指令本身进行编码,忽略“0x20040a”部分,这只是指令的操作数部分,无论如何都会改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多