title: Does gcc really know how to output NASM Assembly
body: <p>So I have a simple C program that loops through the args passed to main then returns:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  
  int main(int argc, char *argv[])
  {
      int i;
      for(i = 0; i &lt; argc; ++i) {
          fprintf(stdout, "%s\n", argv[i]);
      }
      return 0;
  }
  </code></pre>
  
  <p>I wanted to see how gcc wrote out the assembly in NASM format. I was looking over the output in the .asm file and noticed that the syntax was TASM. Below is the make file and the output from gcc. Am I doing something wrong or is it that gcc does not output true NASM syntax?</p>
  
  <pre><code>all: main
  
  main: main.o
          ld -o main main.o
  
  main.o : main.c
          gcc -S -masm=intel -o main.asm main.c
          nasm -f elf -g -F stabs main.asm -l main.lst
  </code></pre>
  
  <p>AND</p>
  
  <pre><code>    .file   "main.c"
      .intel_syntax noprefix
      .section    .rodata
  .LC0:
      .string "%s\n"
      .text
  .globl main
      .type   main, @function
  main:
      push    ebp
      mov ebp, esp
      and esp, -16
      sub esp, 32
      mov DWORD PTR [esp+28], 0
      jmp .L2
  .L3:
      mov eax, DWORD PTR [esp+28]
      sal eax, 2
      add eax, DWORD PTR [ebp+12]
      mov ecx, DWORD PTR [eax]
      mov edx, OFFSET FLAT:.LC0
      mov eax, DWORD PTR stdout
      mov DWORD PTR [esp+8], ecx
      mov DWORD PTR [esp+4], edx
      mov DWORD PTR [esp], eax
      call    fprintf
      add DWORD PTR [esp+28], 1
  .L2:
      mov eax, DWORD PTR [esp+28]
      cmp eax, DWORD PTR [ebp+8]
      jl  .L3
      mov eax, 0
      leave
      ret
      .size   main, .-main
      .ident  "GCC: (GNU) 4.5.1 20100924 (Red Hat 4.5.1-4)"
      .section    .note.GNU-stack,"",@progbits
  </code></pre>
  
  <p>The errors on the command line are:</p>
  
  <pre><code>[mehoggan@fedora sandbox-print_args]$ make
  gcc -S -masm=intel -o main.asm main.c
  nasm -f elf -g -F stabs main.asm -l main.lst
  main.asm:1: error: attempt to define a local label before any non-local labels
  main.asm:1: error: parser: instruction expected
  main.asm:2: error: attempt to define a local label before any non-local labels
  main.asm:2: error: parser: instruction expected
  main.asm:3: error: attempt to define a local label before any non-local labels
  main.asm:3: error: parser: instruction expected
  main.asm:4: error: attempt to define a local label before any non-local labels
  main.asm:5: error: attempt to define a local label before any non-local labels
  main.asm:5: error: parser: instruction expected
  main.asm:6: error: attempt to define a local label before any non-local labels
  main.asm:7: error: attempt to define a local label before any non-local labels
  main.asm:7: error: parser: instruction expected
  main.asm:8: error: attempt to define a local label before any non-local labels
  main.asm:8: error: parser: instruction expected
  main.asm:14: error: comma, colon or end of line expected
  main.asm:17: error: comma, colon or end of line expected
  main.asm:19: error: comma, colon or end of line expected
  main.asm:20: error: comma, colon or end of line expected
  main.asm:21: error: comma, colon or end of line expected
  main.asm:22: error: comma, colon or end of line expected
  main.asm:23: error: comma, colon or end of line expected
  main.asm:24: error: comma, colon or end of line expected
  main.asm:25: error: comma, colon or end of line expected
  main.asm:27: error: comma, colon or end of line expected
  main.asm:29: error: comma, colon or end of line expected
  main.asm:30: error: comma, colon or end of line expected
  main.asm:35: error: parser: instruction expected
  main.asm:36: error: parser: instruction expected
  main.asm:37: error: parser: instruction expected
  make: *** [main.o] Error 1
  </code></pre>
  
  <p>What lead me to believe that this is TASM syntax was information posted at this link:
  <a href="http://rs1.szif.hu/~tomcat/win32/intro.txt" rel="nofollow">http://rs1.szif.hu/~tomcat/win32/intro.txt</a></p>
  
  <blockquote>
    <p>TASM coders usually have lexical difficulties with NASM because it
    lacks the "ptr" keyword used extensively in TASM.</p>
    
    <p>TASM uses this:</p>
    
    <p>mov al,  byte ptr [ds:si] or    mov ax,  word ptr [ds:si] or    mov eax,
    dword ptr [ds:si]</p>
    
    <p>For NASM This simply translates into:</p>
    
    <p>mov al,  byte [ds:si] or    mov ax,  word [ds:si] or    mov eax, dword
    [ds:si]</p>
    
    <p>NASM allows these size keywords in many places, and thus gives you a
    lot of control over the generated opcodes in a unifrom way, for
    example These are all valid:</p>
    
    <p>push dword 123  jmp  [ds: word 1234]   ; these both specify the size
    of the offset     jmp  [ds: dword 1234]  ; for tricky code when
    interfacing 32bit and
                                   ; 16bit segments</p>
    
    <p>it can get pretty hairy, but the important thing to remember is you
    can have all the control you need, when you want it.</p>
  </blockquote>