title: Why does this simple assembly program work in AT&T syntax but not Intel syntax?
body: <p>What's wrong with this code (Running on x86_64 Linux)?</p>
  
  <pre><code>.intel_syntax
  .text
  .globl _start
  
  _start:
      mov rax, 1
      mov rdi, 1
      mov rsi, msg
      mov rdx, 14
      syscall
  
      mov rax, 60
      mov rdi, 0
      syscall
  
  .data
  msg:
      .ascii "Hello, world!\n"
  </code></pre>
  
  <p>When I run it:</p>
  
  <pre><code>$ clang -o hello_intel hello_intel.s  -nostdlib  &amp;&amp; ./hello_intel
  </code></pre>
  
  <p>No output. Let's strace it:</p>
  
  <pre><code>$ strace ./hello_intel
  execve("./hello_intel", ["./hello_intel"], [/* 96 vars */]) = 0
  write(1, 0x77202c6f6c6c6548, 14)        = -1 EFAULT (Bad address)
  exit(0)                                 = ?
  +++ exited with 0 +++
  </code></pre>
  
  <p>It's dereferencing <code>msg</code> instead of using its location. Why?</p>
  
  <p>If I use AT&amp;T syntax instead...</p>
  
  <pre><code>.text
  .globl _start
  
  _start:
      mov $1, %rax
      mov $1, %rdi
      mov $msg, %rsi
      mov $14, %rdx
      syscall
  
      mov $60, %rax
      mov $0, %rdi
      syscall
  
  .data
  msg:
      .ascii "Hello, world!\n"
  </code></pre>
  
  <p>...it works fine:</p>
  
  <pre><code>$ clang -o hello_att hello_att.s  -nostdlib &amp;&amp; ./hello_att
  Hello, world!
  </code></pre>
  
  <p>What's the difference between these two?</p>
  
  <p>Here's the working one:</p>
  
  <pre><code>$ objdump -d hello_att -s -M intel
  
  hello_att:     file format elf64-x86-64
  
  Contents of section .text:
   4000e8 48c7c001 00000048 c7c70100 000048c7  H......H......H.
   4000f8 c6160160 0048c7c2 0e000000 0f0548c7  ...`.H........H.
   400108 c03c0000 0048c7c7 00000000 0f05      .&lt;...H........  
  Contents of section .data:
   600116 48656c6c 6f2c2077 6f726c64 210a      Hello, world!.  
  
  Disassembly of section .text:
  
  00000000004000e8 &lt;_start&gt;:
    4000e8:   48 c7 c0 01 00 00 00    mov    rax,0x1
    4000ef:   48 c7 c7 01 00 00 00    mov    rdi,0x1
    4000f6:   48 c7 c6 16 01 60 00    mov    rsi,0x600116
    4000fd:   48 c7 c2 0e 00 00 00    mov    rdx,0xe
    400104:   0f 05                   syscall 
    400106:   48 c7 c0 3c 00 00 00    mov    rax,0x3c
    40010d:   48 c7 c7 00 00 00 00    mov    rdi,0x0
    400114:   0f 05                   syscall 
  </code></pre>
  
  <p>And here's the broken one:</p>
  
  <pre><code>$ objdump -d hello_intel -s -M intel
  
  hello_intel:     file format elf64-x86-64
  
  Contents of section .text:
   4000e8 48c7c001 00000048 c7c70100 0000488b  H......H......H.
   4000f8 34251701 600048c7 c20e0000 000f0548  4%..`.H........H
   400108 c7c03c00 000048c7 c7000000 000f05    ..&lt;...H........ 
  Contents of section .data:
   600117 48656c6c 6f2c2077 6f726c64 210a      Hello, world!.  
  
  Disassembly of section .text:
  
  00000000004000e8 &lt;_start&gt;:
    4000e8:   48 c7 c0 01 00 00 00    mov    rax,0x1
    4000ef:   48 c7 c7 01 00 00 00    mov    rdi,0x1
    4000f6:   48 8b 34 25 17 01 60    mov    rsi,QWORD PTR ds:0x600117
    4000fd:   00 
    4000fe:   48 c7 c2 0e 00 00 00    mov    rdx,0xe
    400105:   0f 05                   syscall 
    400107:   48 c7 c0 3c 00 00 00    mov    rax,0x3c
    40010e:   48 c7 c7 00 00 00 00    mov    rdi,0x0
    400115:   0f 05                   syscall 
  </code></pre>
  
  <p>So the important difference here is <code>0x600116</code> vs <code>QWORD PTR ds:0x600117</code>, which indeed looks like the difference between a pointer and dereferencing a pointer.</p>
  
  <p>So how do you not dereference the pointer in the Intel syntax code?</p>