Как использовать относительную адресацию RIP в 64-битной программе сборки?

Как использовать относительную адресацию RIP в программе сборки Linux для архитектуры AMD64? Я ищу простой пример (программа Hello world), который использует режим относительной адресации AMD64 RIP.

Например, следующая 64-битная программа сборки будет работать с обычной (абсолютной адресацией):

.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"

Я предполагаю, что та же программа, использующая относительную адресацию RIP, будет выглядеть примерно так:

.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"

Обычная версия работает нормально при компиляции с:

as -o hello.o hello.s && ld -s -o hello hello.o && ./hello

Но я не могу заставить работать версию RIP.

Есть идеи?

--- редактировать ----

Ответ Стивена Кэнона заставляет работать версию RIP.

Теперь, когда я разбираю исполняемый файл версии RIP, я получаю:

objdump -d привет

0000000000400078 <.text>:
  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)

Что показывает то, что я пытался выполнить: lea 0x10 (% rip),% rsi загружает адрес 17 байтов после инструкции lea, которая является адресом 0x400096, где можно найти строку Hello world и, таким образом, получить независимый от позиции код.

Ответы на вопрос(1)

Ваш ответ на вопрос