Question

Comment utiliser l'adressage relatif RIP dans un programme d'assemblage Linux pour l'architecture AMD64 ?Je recherche un exemple simple (un programme Hello world) qui utilise le mode d'adressage relatif AMD64 RIP.

Par exemple, le programme assembleur 64 bits suivant fonctionnerait avec un adressage normal (absolu) :

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

Je suppose que le même programme utilisant RIP Relative Addressing ressemblerait à quelque chose comme :

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

La version normale fonctionne correctement lorsqu'elle est compilée avec :

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

Mais je n'arrive pas à faire fonctionner la version RIP.

Des idées?

--- modifier ----

La réponse de Stephen Canon fait fonctionner la version RIP.

Maintenant, lorsque je démonte l'exécutable de la version RIP, j'obtiens :

objdump -d bonjour

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)

Ce qui montre ce que j'essayais d'accomplir :lea 0x10(%rip),%rsi charge l'adresse 17 octets après l'instruction lea qui est l'adresse 0x400096 où la chaîne Hello world peut être trouvée et aboutissant ainsi à un code indépendant de la position.

Était-ce utile?

La solution

Je crois que vous voulez charger le adresse de votre chaîne dans %rsi;votre code tente de charger un quadword à partir de cette adresse plutôt que de l'adresse elle-même.Tu veux:

lea msg(%rip), %rsi

si je ne me trompe pas.Cependant, je n'ai pas de machine Linux sur laquelle tester.

Autres conseils

Depuis que vous avez besoin de l'adresse de msg in% RSI, il suffit de remplacer:

mov msg(%rip),%rsi

avec:

lea msg(%rip),%rsi

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top