title: How to generate assembly code with gcc that can be compiled with nasm
body: <p>I am trying to learn assembly language as a hobby and I frequently use <code>gcc -S</code> to produce assembly output. This is pretty much straightforward, but I fail to compile the assembly output. I was just curious whether this can be done at all. I tried using both standard assembly output and intel syntax using the <code>-masm=intel</code>. Both can't be compiled with <code>nasm</code> and linked with <code>ld</code>. </p>
  
  <p>Therefore I would like to ask whether it is possible to generate assembly code, that can be then compiled.</p>
  
  <p>To be more precise I used the following C code.</p>
  
  <pre><code> &gt;&gt; cat csimp.c 
   int main (void){
   int i,j;
     for(i=1;i&lt;21;i++)
       j= i + 100;
    return 0;
    }
  </code></pre>
  
  <p>Generated assembly with <code>gcc -S -O0 -masm=intel  csimp.c</code> and tried to compile with <code>nasm -f elf64 csimp.s</code> and link with <code>ld -m elf_x86_64 -s -o test csimp.o</code>. The output I got from nasm reads:</p>
  
  <pre><code>csimp.s:1: error: attempt to define a local label before any non-local labels
  csimp.s:1: error: parser: instruction expected
  csimp.s:2: error: attempt to define a local label before any non-local labels
  csimp.s:2: error: parser: instruction expected
  </code></pre>
  
  <p>This is most probably due to broken assembly syntax. My hope is that I would be able to fix this without having to manually correct the output of <code>gcc -S</code></p>
  
  <hr>
  
  <p><strong>Edit</strong>:</p>
  
  <p>I was given a <a href="https://stackoverflow.com/questions/20737947/how-to-generate-a-nasm-compilable-assembly-code-from-c-source-code-on-linux">hint</a> that my problem is solved in another question; unfortunately, after testing the method described there, I was not able to produce <code>nasm</code> assembly format. You can see the output of <code>objconv</code> below. 
  Therefore I still need your help.</p>
  
  <pre><code>&gt;&gt;cat csimp.asm 
  ; Disassembly of file: csimp.o
  ; Sat Jan 30 20:17:39 2016
  ; Mode: 64 bits
  ; Syntax: YASM/NASM
  ; Instruction set: 8086, x64
  
  global main:  ; **the ':' should be removed !!!** 
  
  
  SECTION .text                                           ; section number 1, code
  
  main:   ; Function begin
          push    rbp                                     ; 0000 _ 55
          mov     rbp, rsp                                ; 0001 _ 48: 89. E5
          mov     dword [rbp-4H], 1                       ; 0004 _ C7. 45, FC, 00000001
          jmp     ?_002                                   ; 000B _ EB, 0D
  
  ?_001:  mov     eax, dword [rbp-4H]                     ; 000D _ 8B. 45, FC
          add     eax, 100                                ; 0010 _ 83. C0, 64
          mov     dword [rbp-8H], eax                     ; 0013 _ 89. 45, F8
          add     dword [rbp-4H], 1                       ; 0016 _ 83. 45, FC, 01
  ?_002:  cmp     dword [rbp-4H], 20                      ; 001A _ 83. 7D, FC, 14
          jle     ?_001                                   ; 001E _ 7E, ED
          pop     rbp                                     ; 0020 _ 5D
          ret                                             ; 0021 _ C3
  ; main End of function
  
  
  SECTION .data                                           ; section number 2, data
  
  
  SECTION .bss                                            ; section number 3, bss
  </code></pre>
  
  <p><strong>Apparent solution:</strong> </p>
  
  <p>I made a mistake when cleaning up the output of <code>objconv</code>. I should have run:</p>
  
  <pre><code>sed -i "s/align=1//g ; s/[a-z]*execute//g ; s/: *function//g;  /default *rel/d" csimp.asm
  </code></pre>
  
  <p>All steps can be condensed in a <code>bash</code> script</p>
  
  <pre><code>#! /bin/bash
  
  a=$( echo $1 | sed  "s/\.c//" ) # strip the file extension .c
  
  # compile binary with minimal information
  gcc -fno-asynchronous-unwind-tables -s -c ${a}.c 
  
  # convert the executable to nasm format
  ./objconv/objconv -fnasm ${a}.o 
  
  # remove unnecesairy objconv information
  sed -i "s/align=1//g ; s/[a-z]*execute//g ; s/: *function//g;  /default *rel/d" ${a}.asm
  
  # run nasm for 64-bit binary
  
  nasm -f elf64 ${a}.asm 
  
  # link --&gt; see comment of MichaelPetch below
  ld -m elf_x86_64 -s ${a}.o 
  </code></pre>
  
  <p>Running this code I get the <code>ld</code> warning:</p>
  
  <pre><code> ld: warning: cannot find entry symbol _start; defaulting to 0000000000400080 
  </code></pre>
  
  <p>The executable produced in this manner crashes with segmentation fault message. I would appreciate your help.</p>