以下代码在gcc6.2中运行得很好:
int main(){
long x, y = 0;
__asm__ (
".data\n\t"
"var_0: .byte 2\n\t"
".text\n\t"
"xor %%eax, %%eax\n\t"
"leaq var_0(%%rax), %%rbx\n\t"
"movb var_0(%%rax), %%al\n\t"
"movq %%rax, %0\n\t"
"movq %%rbx, %1\n\t"
:"=m" (x), "=m" (y)
:
:"%rax", "%rbx"
);
printf("%x %x\n",x, y);
}
此示例输出为2 601031
。这个语法告诉我gcc(或者我认为是气体)使用指令相对寻址。如果我用
"leaq var_0(%%rip), %%rbx\n\t"
"movb var_0(%%rip), %%al\n\t"
然后输出再次2 601031
(编辑:前面的语句不正确,因为我输出的代码略有不同)。我不知道记录在哪里,但它很棒。但是,当我升级到gcc6.3时,RIP相对寻址版本仍能正常工作,但指令相对版本会产生错误
/usr/bin/ld: /tmp/cc2E9Upc.o: relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
即使我使用gcc -fPIC
重新编译。有人能告诉我两个版本的gcc之间发生了什么?我需要注意哪些变化?我需要使用的旗帜?
编辑2:与objdump
一起玩,让我清楚地知道这个标题是无稽之谈。 Gcc6.2只使用可执行文件中var_0
的翻译地址。我想知道为什么这对于gcc4.3没有用,我为匆匆写的标题道歉。