title: How to use RIP Relative Addressing in a 64-bit assembly program?
body: <p>How do I use RIP Relative Addressing in a Linux assembly program for the AMD64 archtitecture?
  I am looking for a simple example (a Hello world program) that uses the AMD64 RIP relative adressing mode.</p>
  
  <p>For example the following 64-bit assembly program would work with normal (absolute addressing):</p>
  
  <pre><code>.text
      .global _start
  
  _start:
      mov $0xd, %rdx
  
      mov $msg, %rsi
      pushq $0x1
      pop %rax
      mov %rax, %rdi
      syscall
  
      xor %rdi, %rdi
      pushq $0x3c
      pop %rax
      syscall
  
  .data
  msg:
      .ascii    "Hello world!\n"
  </code></pre>
  
  <p>I am guessing that the same program using RIP Relative Addressing would be something like:</p>
  
  <pre><code>.text
      .global _start
  
  _start:
      mov $0xd, %rdx
  
      mov msg(%rip), %rsi
      pushq $0x1
      pop %rax
      mov %rax, %rdi
      syscall
  
      xor %rdi, %rdi
      pushq $0x3c
      pop %rax
      syscall
  
  msg:
      .ascii    "Hello world!\n"
  </code></pre>
  
  <p>The normal version runs fine when compiled with:</p>
  
  <pre><code>as -o hello.o hello.s &amp;&amp; ld -s -o hello hello.o &amp;&amp; ./hello
  </code></pre>
  
  <p>But I can't get the RIP version working.</p>
  
  <p>Any ideas?</p>
  
  <p>--- edit ----</p>
  
  <p>Stephen Canon's answer makes the RIP version work.</p>
  
  <p>Now when I disassemble the executable of the RIP version I get:</p>
  
  <p>objdump -d hello</p>
  
  <pre><code>0000000000400078 &lt;.text&gt;:
    400078: 48 c7 c2 0d 00 00 00  mov    $0xd,%rdx
    40007f: 48 8d 35 10 00 00 00  lea    0x10(%rip),%rsi        # 0x400096
    400086: 6a 01                 pushq  $0x1
    400088: 58                    pop    %rax
    400089: 48 89 c7              mov    %rax,%rdi
    40008c: 0f 05                 syscall 
    40008e: 48 31 ff              xor    %rdi,%rdi
    400091: 6a 3c                 pushq  $0x3c
    400093: 58                    pop    %rax
    400094: 0f 05                 syscall 
    400096: 48                    rex.W
    400097: 65                    gs
    400098: 6c                    insb   (%dx),%es:(%rdi)
    400099: 6c                    insb   (%dx),%es:(%rdi)
    40009a: 6f                    outsl  %ds:(%rsi),(%dx)
    40009b: 20 77 6f              and    %dh,0x6f(%rdi)
    40009e: 72 6c                 jb     0x40010c
    4000a0: 64 21 0a              and    %ecx,%fs:(%rdx)
  </code></pre>
  
  <p>Which shows what I was trying to accomplish: lea 0x10(%rip),%rsi loads the address 17 bytes after the lea instruction which is address 0x400096 where the Hello world string can be found and thus resulting in position independent code.</p>