Domanda

Come posso utilizzare Rip relativo indirizzamento in un programma di assembly Linux per l'architettura AMD64? Sto cercando un semplice esempio (un programma Hello World) che utilizza la modalità di indirizzo relativa AMD64 RIP relativa.

Ad esempio, il seguente programma di assembly a 64 bit funzionerà con normale (indirizzamento assoluto):

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

Indovina che lo stesso programma usando la rivolta relativa di RIP sarebbe qualcosa come:

.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 versione normale funziona bene se compilata con:

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

Ma non riesco a far funzionare la versione RIP.

Qualche idea?

--- Modifica ----

La risposta di Stephen Canon rende il funzionamento della versione RIP.

Ora quando smontare l'eseguibile della versione RIP ottengo:

objdump -d hello

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

che mostra quello che stavo cercando di realizzare: Lea 0x10 (% RIP),% RSI carica l'indirizzo 17 Byte dopo l'istruzione Lea che è l'indirizzo 0x400096 in cui è possibile trovare la stringa del mondo ciao e quindi con conseguente posizione di posizione.

È stato utile?

Soluzione

credo che tu voglia caricare l'indirizzo della stringa in %rsi;Il tuo codice tenta di caricare un quadword da quell'indirizzo piuttosto che l'indirizzo stesso.Vuoi:

lea msg(%rip), %rsi
.

Se non sono sbagliato.Non ho una scatola Linux da testare, comunque.

Altri suggerimenti

Dal momento che è necessario l'indirizzo di MSG in% RSI, basta sostituire:

mov msg(%rip),%rsi
.

Con:

lea msg(%rip),%rsi
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top