Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 重新定位被截断以适应:R_X86_64_32_C_Gcc_Assembly_Extern - Fatal编程技术网

C 重新定位被截断以适应:R_X86_64_32

C 重新定位被截断以适应:R_X86_64_32,c,gcc,assembly,extern,C,Gcc,Assembly,Extern,我有一个C驱动程序文件,它声明了一个extern函数,以便在我的asm文件中使用它。我在Windows7x64机器上 我使用以下命令将asm文件与NASM组合在一起: nasm avxmain.asm-f win64-o avxmain.o 然后我编译了C文件,如下所示: gcc avxdriver.c-c-m64-o avxdriver.o 将所有这些联系在一起,我运行: gcc avxdriver.o avxmain.o-o最终版本 以下是我得到的错误: avxmain.o:G:\Deskt

我有一个
C
驱动程序文件,它声明了一个
extern
函数,以便在我的
asm
文件中使用它。我在Windows7x64机器上

我使用以下命令将
asm
文件与
NASM
组合在一起:

nasm avxmain.asm-f win64-o avxmain.o

然后我编译了
C
文件,如下所示:

gcc avxdriver.c-c-m64-o avxdriver.o

将所有这些联系在一起,我运行:

gcc avxdriver.o avxmain.o-o最终版本

以下是我得到的错误:

avxmain.o:G:\Desktop\CPSC240:(.text+0x50):重新定位被截断为 fit:R_X86_64_32与`.bss'

avxmain.o:G:\Desktop\CPSC240:(.text+0xb9):重新定位被截断为 fit:R_X86_64_32与`.data'

avxmain.o:G:\Desktop\CPSC240:(.text+0xc2):重新定位被截断为 fit:R_X86_64_32与`.data'

avxmain.o:G:\Desktop\CPSC240:(.text+0x14e):重新定位被截断为 fit:R_X86_64_32与`.bss'

collect2:错误:ld返回1个出口 地位


avxdriver.c
文件:
#包括
#包括
extern-double-avxdemo();
int main()
{
双返回_码=-99.9;
printf(“%s”,“此程序将测试是否存在AVX(高级向量扩展),也称为状态组件编号2。\n”);
return_code=avxdemo();
printf(“%s%1.12lf\n”,“返回给驱动程序的值为”,返回\u代码);
printf(“%s”,“驱动程序下一步将向操作系统发送一个零。请欣赏您的编程。\n”);
返回0;
}
avxmain.asm
文件:

我把它贴在这里是因为它很长,因为它是由教授提供的评论


我已尝试运行
-fPIC
-mcmodel=medium
选项。我仍然会犯同样的错误。
我完全不知所措,因为这是我应该为我的班级运行的示例项目。这个题目对我来说是全新的。我花了大约半天的时间搜索这些错误并尝试不同的事情。我只需要指出正确的方向。

问题是,通用x64指令不允许在编码中使用直接64位地址。有两种解决方法:

  • 使用
    movabs-rax,symbolname here
    指令将
    rax
    设置为地址,然后使用
    [rax]
    访问该地址的数据

  • 使用
    [rel symbolname here]
    作为操作数;这将在此处创建对
    symbolname
    的PC相对引用。它被编码为32位有符号偏移量,与执行该指令时的
    rip
    不同


  • 方法1允许您对指令中的绝对地址进行编码,而方法2是较小的代码(您可以始终执行
    lea-rax[rel-symbolname here]
    ,以获得与方法1相同的效果)。

    问题是,一般x64指令不允许在其编码中使用直接64位地址。有两种解决方法:

  • 使用
    movabs-rax,symbolname here
    指令将
    rax
    设置为地址,然后使用
    [rax]
    访问该地址的数据

  • 使用
    [rel symbolname here]
    作为操作数;这将在此处创建对
    symbolname
    的PC相对引用。它被编码为32位有符号偏移量,与执行该指令时的
    rip
    不同


  • 方法1允许您对指令中的绝对地址进行编码,而方法2是较小的代码(您总是可以使用
    lea-rax[rel-symbolname here]
    来获得与方法1相同的效果)。

    您应该在
    avxmain.o
    上使用
    objdump-d
    来找出链接器抱怨的语句。但是,很明显问题出在哪些说明上:

    xrstor     [backuparea]
    vmovupd ymm0, [testdata]  
    vmovupd ymm1, [testdata+32] 
    xsave      [backuparea] 
    
    正如Drew McGowen所解释的,问题在于64位指令集无法将这些地址编码为指令中的64位值。相反,它们变成32位有符号置换,有符号置换扩展到64位以创建有效地址。显然,Windows在地址范围内从
    0xFFFFF88`00000000
    开始加载64位驱动程序,因此截断的32位位移不会得到符号扩展回正确的值

    您应该能够像Drew McGowen建议的那样使用RIP相对寻址来解决这个问题。在这种情况下,汇编器应生成链接器不会抱怨的PC相对(RIP相对)重定位:

    xrstor     [rel backuparea]
    vmovupd ymm0, [rel testdata]  
    vmovupd ymm1, [rel + testdata+32] 
    xsave      [rel backuparea] 
    

    您应该在
    avxmain.o
    上使用
    objdump-d
    来找出链接器抱怨的语句。但是,很明显问题出在哪些说明上:

    xrstor     [backuparea]
    vmovupd ymm0, [testdata]  
    vmovupd ymm1, [testdata+32] 
    xsave      [backuparea] 
    
    正如Drew McGowen所解释的,问题在于64位指令集无法将这些地址编码为指令中的64位值。相反,它们变成32位有符号置换,有符号置换扩展到64位以创建有效地址。显然,Windows在地址范围内从
    0xFFFFF88`00000000
    开始加载64位驱动程序,因此截断的32位位移不会得到符号扩展回正确的值

    您应该能够像Drew McGowen建议的那样使用RIP相对寻址来解决这个问题。在这种情况下,汇编器应生成链接器不会抱怨的PC相对(RIP相对)重定位:

    xrstor     [rel backuparea]
    vmovupd ymm0, [rel testdata]  
    vmovupd ymm1, [rel + testdata+32] 
    xsave      [rel backuparea] 
    

    你试过asm代码中的
    default rel
    吗?@harold你能解释一下那是什么吗?我对汇编编程还是一个新手,但我正在采取步骤学习它。基本上相当于使用
    [rel-label]
    到处使用
    [label]
    你在asm代码中尝试过
    默认rel
    吗?@harold你能解释一下这是什么吗?我对汇编编程还是个新手,但我正在采取步骤学习它。基本上相当于使用
    [rel-label]
    随处使用