【问题标题】:Inline asm: move imm to a 64-bit register without sign-extension内联 asm:将 imm 移动到不带符号扩展的 64 位寄存器
【发布时间】:2015-11-06 18:20:07
【问题描述】:

我想使用内联汇编将 64 位无符号整数移动到寄存器中。如果常量实际上适合 32 位,则会发生这种情况。

这是我的代码:

#include "stdint.h"
uint64_t foo() {
    uint64_t x;
    asm ("movq %1, %0"
         : "=q" (x)
         : "i" (0x00000000faceffff) );
    return x;
}

现在,clang -S code.c 生成以下程序集:

#APP    
movq    $-87097345, %rax        # imm = 0xFFFFFFFFFACEFFFF
#NO_APP

gcc 也是如此。 movabsq 代替 movq 也是如此。 "p" 约束而不是 "i" 相同。

如果常数大于 32 位,我会得到预期的结果。

【问题讨论】:

  • 删除了之前的评论,因为它现在在答案中。稍后将删除此评论。
  • 如果它适合 32 位,则首先不需要 64 位 mov。
  • @harold,我确实需要它,因为在我的实际用例中,我想要修补通常为 64 位的常量(地址)。

标签: c x86-64 inline-assembly


【解决方案1】:

常量是否有后缀来用 gcc 将它们声明为 unsigned long long?对于 Microsoft 编译器,在本例中为“...ull” 0x00000000facefffffull。

【讨论】:

  • 这几乎让我怀疑是否选择了这个例子,知道答案是什么!
  • @Hurkyl,哈哈。不,这完全是无意的:)
  • 我的错误是我忘记了 0x00000000faceffff 是一个 C 常数,而不仅仅是一些字符串。无论编译器如何,答案都是正确的,ull 根据标准 (en.cppreference.com/w/cpp/language/integer_literal) 是 unsigned long long int 的前缀。
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-07-20
  • 2017-04-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
相关资源
最近更新 更多