title: What is the correct way to link assembly code with C code using gcc
body: <p>Suppose you have the following assembly files:</p>
  
  <pre><code>  .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
  </code></pre>
  
  <p>and </p>
  
  <pre><code>  .file "string.s"
    .intel_syntax noprefix
  
    .data
  
    .globl hello_string
    .type hello_string, @object
  hello_string:
    .string "Hello, world!\n"
    .size hello_string, 14
  </code></pre>
  
  <p>If you run <code>as string.s -o string.o</code>, <code>as print.s -o print.o</code> and then <code>ld *.o -o hello.elf</code>, you get a executable file which prints Hello, world!. Now suppose that you change the <code>_start</code> label in print.s to <code>print</code> and you have the following C file:</p>
  
  <pre><code>// main.c
  void print(void);
  
  int main (void) {
    print();
    return 0;
  }
  </code></pre>
  
  <p>I want to run something like <code>gcc -o main.elf main.c string.s print.s</code> to take my two assembly files and link them into the standard C runtime. This command as written doesn't work. I get the following error message:</p>
  
  <pre><code>/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
  </code></pre>
  
  <p>I can't figure out how to correctly use the -fPIC flag to make things work. 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. I haven't been able to find much information about this online. </p>
  
  <blockquote>
    <p><b> Question: </b> How do you correctly use the GNU linker to link assembly files into the C runtime?</p>
  </blockquote>
  
  <p>EDIT: In <a href="https://stackoverflow.com/questions/8691138/how-to-link-a-c-object-file-with-a-assembly-language-object-file">How to link a C object file with a Assembly Language object file?</a>, the OP is asking about how to solve a similar linking problem just using <code>ld</code>. I want to use <code>gcc</code> which is the recommended solution in the linked question, but I can't even get that to work.</p>