GCC指令相对寻址

GCC指令相对寻址,gcc,assembly,gnu-assembler,Gcc,Assembly,Gnu Assembler,以下代码在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 %%r

以下代码在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(或者我想是gas)使用指令相对寻址。如果我将上面的行替换为

"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不能使用它,同时我为仓促编写的标题道歉。

试着用
-fno-pie
@Ross Ridge编译,同样的问题这是一个较新版本的Debian或Ubuntu(或基于Debian/Ubuntu的系统的较新版本)?我没有提供答案,只是一个有理由的评论。较新的Ubuntus和Debian的区别在于编译器在构建可执行文件时使用了不同的隐式选项集。其中之一是,默认情况下,当目标为64位时,所有内容都构建为位置独立的代码和位置独立的可执行文件。在这些发行版的旧版本中,可执行文件不是作为独立于位置的文件构建的。我不认为<代码>静态<代码>一个解决方案,只是想知道它是否正确构建。@伊凡<代码> -FPIC选项不起作用,因为它只影响代码GCC生成,而不是您输入的代码<代码> ASM语句。试试gcc-fno pie test.c