【问题标题】:Inline assembly returns: relocation R_X86_64_32S against undefined symbol can not be used when making a shared object [duplicate]内联汇编返回:在制作共享对象时不能使用针对未定义符号的重定位 R_X86_64_32S [重复]
【发布时间】:2018-08-12 00:09:38
【问题描述】:

我正在处理Xeno Kovah's example in slide 18 of Intermediate Assembly。他正在将 Visual Studios 与 Intel Assembly 内联使用。我已经尝试将其适应 GCC,如下所示。我正在使用-masm=intel -fPIC进行编译

#include <stdio.h>
int main(){
  unsigned int maxBasicCPUID;
  char vendorString[13];
  char * vendorStringPtr = (char *)vendorString; //Move the address into its own register
  //because it makes the asm syntax easier
  //First we will check whether we can even use CPUID
  //Such a check is actually more complicated than it seems (OMITED FROM SLIDES)

  __asm (
    "mov edi, vendorStringPtr;" //Get the base address of the char[] into a register
    "mov eax, 0;" //We're going to do CPUID with input of 0
    "cpuid;" //As stated, the instruction doesn't have any operands
    //Get back the results which are now stored in eax, ebx, ecx, edx
    //and will have values as specified by the manual
    "mov maxBasicCPUID, eax;"
    "mov [edi], ebx;" //We order which register we put into which address
    "mov [edi+4], edx;" //so that they all end up forming a human readable string
    "mov [edi+8], ecx;"
  );
  vendorString[12] = 0;
  printf("maxBasicCPUID = %#x, vendorString = %s\n", maxBasicCPUID, vendorString);
  return 0xb45eba11;
}

我不确定我做错了什么,但我收到以下错误

/usr/bin/ld: /tmp/ccSapgOG.o: relocation R_X86_64_32S against undefined symbol `vendorStringPtr' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

【问题讨论】:

标签: gcc assembly x86 inline-assembly


【解决方案1】:

在 gcc 中,不能在汇编代码中直接按名称引用局部变量。

另外,你需要告诉编译器你使用的所有寄存器(clobber)。

但是,从好的方面来说,您可以让编译器为您完成更多工作,正如您在以下代码重写中看到的那样:

   uint32_t *str = (uint32_t *)vendorString;
   __asm("cpuid"
       : "=a"(maxBasicCPUID), "=b"(str[0]), "=d"(str[1]), "=c"(str[2])
       : "a"(0));

第一行参数告诉编译器将结果存储在哪里,第二行告诉编译器在执行内联汇编之前要加载哪些值。

有关所有详细信息,请参阅https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html。 (感谢@MichaelPetch 提供链接。)

【讨论】:

    猜你喜欢
    • 2017-04-10
    • 1970-01-01
    • 2017-07-23
    • 2018-06-19
    • 1970-01-01
    • 2016-06-06
    • 2020-01-17
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多