我有一个C
驱动程序文件,它声明了一个extern
函数,以便在我的asm
文件中使用它。我在Windows 7 x64机器上。
我使用此命令将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 final
以下是我遇到的错误:
avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0x50):重定位被截断为 适合:对于`.bss'
,R_X86_64_32avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0xb9):重定位被截断为 适合:对于`.data'
,R_X86_64_32avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0xc2):重定位被截断为 适合:对于`.data'
,R_X86_64_32avxmain.o:G:\ Desktop \ CPSC240 :(。text + 0x14e):重定位被截断为 适合:R_X86_64_32反对`.bss'
collect2:错误:ld返回1退出 状态
avxdriver.c
档案:#include <stdio.h>
#include <stdint.h>
extern double avxdemo();
int main()
{
double return_code = -99.9;
printf("%s","This program will test for the presence of AVX (Advanced Vector Extensions) also known as state component number 2.\n");
return_code = avxdemo();
printf("%s %1.12lf\n","The value returned to the driver is ", return_code);
printf("%s","The driver program will next send a zero to the operating system. Enjoy your programming.\n");
return 0;
}
avxmain.asm
档案:我在这里发帖是因为教授提供的评论很长。
我尝试过运行-fPIC
和-mcmodel=medium
选项。我仍然得到同样的错误。
我完全迷失了,因为这是我应该为我的课程运行的示例项目。这个主题对我来说是全新的。我花了大约一半的时间来搜索这些错误并尝试不同的事情。我只需指出正确的方向。
答案 0 :(得分:4)
问题是一般的x64指令不允许在其编码中使用直接的64位地址。有两种方法:
使用movabs rax, symbolNameHere
指令将rax
设置为该地址,然后使用[rax]
访问该地址的数据。
使用[rel symbolNameHere]
作为操作数;这会创建与symbolNameHere
的PC相关引用。它被编码为执行该指令时所有rip
的32位有符号偏移量。
方法1允许您对指令中的绝对地址进行编码,而方法2则是较小的代码(您可以始终执行lea rax, [rel symbolNameHere]
以获得与方法1相同的效果。)
答案 1 :(得分:2)
您应该在objdump -d
上使用avxmain.o
来查找链接器抱怨的语句。但是很清楚哪些指令是问题所在:
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]