C 内联asm:将imm移动到不带符号扩展的64位寄存器
我想使用内联asm将64位无符号整数移动到寄存器。如果常量实际上适合32位,那么它就会得到符号扩展 这是我的密码:C 内联asm:将imm移动到不带符号扩展的64位寄存器,c,x86-64,inline-assembly,C,X86 64,Inline Assembly,我想使用内联asm将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
#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也是如此。用movabq
代替movq
也一样。与“p”
约束相同,而不是“i”
如果常量大于32位,我会得到预期的结果。是否有一个后缀用于将常量声明为gcc中的无符号long long?对于Microsoft编译器,在本例中为“…ull”,即0x00000000Facefffull。删除了以前的注释,因为它现在位于答案中。稍后将删除此注释。如果它适合32位,您首先不需要64位mov。@harold,我确实需要它,因为在我的实际用例中,我希望修补通常为64位的常量(一个地址)。这几乎让我怀疑是否选择了示例,知道答案是什么@Hurkyl,哈哈。不,这完全是无意的:)我的错误是我忘记了
0x00000000faceffff
是一个C常量,而不仅仅是一些字符串。不管编译器是什么,答案都是正确的,ull
是标准(en.cppreference.com/w/cpp/language/integer\u literal)中的无符号长整型int
的前缀。