title: Can gcc compile x86 assembly or just link it?
body: <p>gcc can produce assembly but how do I compile pure assembly with gcc or other compiler? I know x86 assembly is difficult and another instruction set than the MIPS and Nios I was looking at but now I want to try to compile direct x86 asm. There are instruction for how to do it but there's a C file included and I don't need a C file for my first most basic compile.</p>
  
  <pre><code>gcc -o test_asm asm_functions.S test_asm.c
  </code></pre>
  
  <p>There's the step creating <code>.o</code> files</p>
  
  <pre><code>gcc -c asm_functions.S
  gcc -c test_asm.c
  gcc -o test_asm asm_functions.o test_asm.o
  </code></pre>
  
  <p>But I don't see the step where I can directly compile x86 asm with gcc. There's another program named GNU as (GNU Assembler), can it be used to translate x86 assembly to machine code? </p>
  
  <h2>Test</h2>
  
  <p>Code (32.s)</p>
  
  <pre><code>.globl  _start
  
  .text
  _start:
          movl    $len, %edx
          movl    $msg, %ecx
          movl    $1, %ebx
          movl    $4, %eax
          int     $0x80
  
          movl    $0, %ebx
          movl    $1, %eax
          int     $0x80
  .data
  msg:
          .ascii  "Hello, world!\n"
          len =   . - msg
  </code></pre>
  
  <p>Steps</p>
  
  <pre><code>$ gcc -c 32.s 
  $ ls 32*
  32.o  32.s
  $ gcc -o 32 32.o 
  32.o: In function `_start':
  (.text+0x0): multiple definition of `_start'
  /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here
  /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
  (.text+0x20): undefined reference to `main'
  </code></pre>
  
  <p>So it seems it may have mixed 32 and 64 bits, must I tell the complier whether the assembly is 32 or 64 bit instructions?</p>
  
  <h2>Update</h2>
  
  <p>This test worked with gcc.</p>
  
  <pre><code>$ cat hello.s
  .data
  .globl hello
  hello:
  .string "Hi World\n"
  
  .text
  .global main
  main:
      pushq   %rbp
      movq    %rsp,       %rbp
      movq    $hello,     %rdi
      call    puts
      movq    $0,         %rax
      leave
      ret
  $ gcc hello.s -o hello
  $ ./hello 
  Hi World
  </code></pre>