简体   繁体   English

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

[英]What is the correct way to link assembly code with C code using gcc

Suppose you have the following assembly files: 假设您具有以下程序集文件:

  .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

and

  .file "string.s"
  .intel_syntax noprefix

  .data

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

If you run as string.s -o string.o , as print.s -o print.o and then ld *.o -o hello.elf , you get a executable file which prints Hello, world!. 如果您as string.s -o string.o as print.s -o print.o运行, as print.s -o print.o ,然后以ld *.o -o hello.elf ,您将获得一个可执行文件,该文件显示Hello,world!。 Now suppose that you change the _start label in print.s to print and you have the following C file: 现在,假设您将print.s中的_start标签更改为print并且具有以下C文件:

// main.c
void print(void);

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

I want to run something like gcc -o main.elf main.c string.s print.s to take my two assembly files and link them into the standard C runtime. 我想运行gcc -o main.elf main.c string.s print.s以获取我的两个程序集文件并将它们链接到标准C运行时中。 This command as written doesn't work. 编写的此命令无效。 I get the following error message: 我收到以下错误消息:

/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

I can't figure out how to correctly use the -fPIC flag to make things work. 我无法弄清楚如何正确使用-fPIC标志使事情正常进行。 I am not even sure if that is what I should be doing. 我什至不确定那是我应该做的。 I could try and use the inline assembler to do this, but for my actual use cases, that would be extremely annoying and I would much rather learn how to correctly link assembly chunks into my C programs. 我可以尝试使用内联汇编器执行此操作,但是对于我的实际用例而言,这将非常烦人,而我宁愿学习如何将汇编块正确链接到C程序中。 I haven't been able to find much information about this online. 我目前无法在网上找到太多信息。

Question: How do you correctly use the GNU linker to link assembly files into the C runtime? 问题:如何正确使用GNU链接器将程序集文件链接到C运行时?

EDIT: In How to link a C object file with a Assembly Language object file? 编辑:在如何将C对象文件与汇编语言对象文件链接? , the OP is asking about how to solve a similar linking problem just using ld . ,OP正在询问如何仅使用ld解决类似的链接问题。 I want to use gcc which is the recommended solution in the linked question, but I can't even get that to work. 我想使用gcc ,这是链接问题中的推荐解决方案,但我什至无法使它起作用。

OK, so I have figured it out now. 好,所以我现在想通了。 The error message seems to be telling me that gcc is trying to make a shared object. 错误消息似乎告诉我gcc正在尝试创建共享对象。 This lead me to the question gcc 6.2.0 is attempting to create shared object when it shouldn't? 这使我想到gcc 6.2.0是否在不应该尝试创建共享库的问题

The solution is to run gcc -no-pie main.c string.s print.s -o main.elf 解决方案是运行gcc -no-pie main.c string.s print.s -o main.elf

according to the man page, -no-pie tells gcc to not produce a position indipendent executable. 根据手册页, -no-pie告诉gcc不产生位置独立的可执行文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM