使用gcc将汇编代码与C代码链接的正确方法是什么

时间:2018-05-05 05:35:45

标签: c assembly x86-64

假设您有以下程序集文件:

  .file "print.s"
  .intel_syntax noprefix

  .text

  .globl _start
  .type _start, @function
_start:
  mov rax, 1
  mov rdi, 1
  lea rsi, hello_string
  mov rdx, 14
  syscall
  mov rax, 60
  mov rdi, 0
  syscall
  .size _start, .-_start

  .file "string.s"
  .intel_syntax noprefix

  .data

  .globl hello_string
  .type hello_string, @object
hello_string:
  .string "Hello, world!\n"
  .size hello_string, 14

如果您运行as string.s -o string.oas print.s -o print.o,然后ld *.o -o hello.elf,则会获得一个打印Hello,world!的可执行文件。现在假设您将print.s中的_start标签更改为print,并且您拥有以下C文件:

// main.c
void print(void);

int main (void) {
  print();
  return 0;
}

我想运行类似gcc -o main.elf main.c string.s print.s的东西来获取我的两个汇编文件并将它们链接到标准C运行时。写的这个命令不起作用。我收到以下错误消息:

/usr/bin/ld: /tmp/ccc1yRif.o: relocation R_X86_64_32S against symbol `hello_string' can not be used when making a shared object; recompile with -fPIC

我无法弄清楚如何正确使用-fPIC标志来使事情发挥作用。我甚至不确定这是不是我应该做的。我可以尝试使用内联汇编程序来执行此操作,但对于我的实际用例,这将非常烦人,我更愿意学习如何正确地将程序集块链接到我的C程序中。我还没能在网上找到很多这方面的信息。

  

问题:如何正确使用GNU链接器将汇编文件链接到C运行时?

编辑:在How to link a C object file with a Assembly Language object file?中,OP正在询问如何使用ld解决类似的链接问题。我想使用gcc这是链接问题中推荐的解决方案,但我甚至无法让它发挥作用。

1 个答案:

答案 0 :(得分:0)

好的,所以我现在已经弄明白了。错误消息似乎告诉我gcc正在尝试创建一个共享对象。这引出了我的问题gcc 6.2.0 is attempting to create shared object when it shouldn't?

解决方案是运行gcc -no-pie main.c string.s print.s -o main.elf

根据手册页,-no-pie告诉gcc不生成位置独立的可执行文件。