我有一些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);
}
我正在编译并在我的(英特尔)Mac笔记本电脑上运行.
代码的输出似乎有所不同,这取决于我是用(GNU)GCC还是Clang编译的.
我为GCC编译了gnucc -o gnu-test test.c
(我从https://gcc.gnu.org/install/download.html下载源代码后,在我的Mac上从源代码构建了gnucc
),为Clang(内置MacOS Clang)编译了clang -o clang-test test.c
.
在我的Mac上,使用GNU,结果是2
(这是我预期的).有了Cang,结果是140701838959608
.
在我看来,Clang的结果似乎是错误的,但我也在想,也许是我的内联汇编不太正确,而GCC只是碰巧没有expose 我的错误.
我在Compiler Explorer上try 了相同的代码,GCC(x86-64 GCC 13.2给2
)和Clang(x86-64 Clang 16.0.0给140726522786920
)的输出也不同.
我try 反汇编带有objdump -d
的Clang二进制代码:
clang-test: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000100003f60 <_main>:
100003f60: 55 pushq %rbp
100003f61: 48 89 e5 movq %rsp, %rbp
100003f64: 48 83 ec 20 subq $32, %rsp
100003f68: 89 7d fc movl %edi, -4(%rbp)
100003f6b: 48 89 75 f0 movq %rsi, -16(%rbp)
100003f6f: 48 c7 45 e8 00 00 00 00 movq $0, -24(%rbp)
100003f77: 48 8d 45 e8 leaq -24(%rbp), %rax
100003f7b: b9 02 00 00 00 movl $2, %ecx
100003f80: 48 89 00 movq %rax, (%rax)
100003f83: 48 8b 75 e8 movq -24(%rbp), %rsi
100003f87: 48 8d 3d 16 00 00 00 leaq 22(%rip), %rdi ## 0x100003fa4 <_printf+0x100003fa4>
100003f8e: b0 00 movb $0, %al
100003f90: e8 09 00 00 00 callq 0x100003f9e <_printf+0x100003f9e>
100003f95: 31 c0 xorl %eax, %eax
100003f97: 48 83 c4 20 addq $32, %rsp
100003f9b: 5d popq %rbp
100003f9c: c3 retq
Disassembly of section __TEXT,__stubs:
0000000100003f9e <__stubs>:
100003f9e: ff 25 5c 00 00 00 jmpq *92(%rip) ## 0x100004000 <_printf+0x100004000>
而100003f80: 48 89 00 movq %rax, (%rax)
似乎是问题所在?Clang在ecx
中具有正确的值,在rax
中具有正确的写入地址,但它使用movq %rax, (%rax)
而不是movq %rcx, (%rax)
?