Dav*_*vid 17 c clang inline-assembly
我有一些 C 代码:
#include "stdio.h"
typedef struct num {
unsigned long long x;
} num;
int main(int argc, char **argv) {
struct num anum;
anum.x = 0;
__asm__("movq %%rax, %0\n" : "=m" (anum.x) : "rax"(2));
printf("%llu\n",anum.x);
}
Run Code Online (Sandbox Code Playgroud)
我正在我的(英特尔)Mac 笔记本电脑上编译并运行它。
代码的输出似乎有所不同,具体取决于我使用 (GNU) GCC 还是 Clang 进行编译。gnucc -o gnu-test test.c我使用GCC(从https://gcc.gnu.org/install/download.htmlgnucc下载源代码后在 Mac 上从源代码构建)和Clang(内置 macOS Clang)进行编译。clang -o clang-test test.c
在我的 Mac 上,使用 GNU,结果是2(这是我所期望的)。使用 Clang,结果是140701838959608.
Clang 结果对我来说似乎是错误的,但我也想知道我的内联汇编是否不太正确,而 GCC 恰好没有暴露我的错误。
我在Compiler Explorer上尝试了相同的代码, GCC(x86-64 GCC 13.2 给出2)和 Clang(x86-64 Clang 16.0.0 给出)的输出也不同140726522786920。
我尝试用以下命令反汇编 Clang 二进制文件objdump -d:
#include "stdio.h"
typedef struct num {
unsigned long long x;
} num;
int main(int argc, char **argv) {
struct num anum;
anum.x = 0;
__asm__("movq %%rax, %0\n" : "=m" (anum.x) : "rax"(2));
printf("%llu\n",anum.x);
}
Run Code Online (Sandbox Code Playgroud)
似乎100003f80: 48 89 00 movq %rax, (%rax)是问题所在?Clang 具有正确的值 inecx和要写入的正确地址 in rax,但它movq %rax, (%rax)代替了movq %rcx, (%rax)?
int*_*jay 29
Clang 正在生成正确的代码,但您对输入操作数指定了不正确的约束。
约束 ( "rax") 不被解释为寄存器名称。相反,约束中的每个字母指定一个允许的操作数类型。这里的第一个字母r,允许使用任何通用寄存器,这使得选择rcx有效。
要约束寄存器rax,需要使用"a"约束。请参阅机器限制页面中的 x86 部分。
__asm__("movq %%rax, %0\n" : "=m" (anum.x) : "a"(2));
Run Code Online (Sandbox Code Playgroud)