¿Cómo uso el direccionamiento relativo de RIP en un programa de ensamblaje de Linux para la arquitectura de AMD64? Estoy buscando un ejemplo simple (un programa Hello mundial) que use el modo de direccionamiento relativo AMD64 RIP.¿Cómo usar el direccionamiento relativo de RIP en un programa de ensamblaje de 64 bits?
Por ejemplo, el siguiente programa de montaje de 64 bits que trabajaría con normal (direccionamiento absoluto):
.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"
estoy adivinando que el mismo programa usando RIP direccionamiento relativo sería algo como:
.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 versión normal funciona muy bien cuando se compila con:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
Pero no puedo hacer funcionar la versión RIP.
¿Alguna idea?
--- ---- edición
la respuesta de Stephen Canon hace que el trabajo de la versión RIP.
Ahora, cuando desmonte el ejecutable de la versión RIP me sale:
objdump -d hola
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)
que muestra lo que estaba tratando de lograr: 0x10 LEA (% RIP), RSI% carga la dirección 17 bytes después de la instrucción lea, que es la dirección 0x400096 donde se puede encontrar la cadena Hello world y, por lo tanto, resulta en un código de posición independiente.
¿Por qué 17 bytes después (0x10 es 16)? – fadedbee
https://www.tortall.net/projects/yasm/manual/html/nasm-effaddr.html dice: 'RIP es el registro de puntero de instrucción, que contiene la dirección de la ubicación inmediatamente después de la instrucción actual' pero' La instrucción lea' tiene siete bytes de longitud, no una. – fadedbee
¿Por qué 'push' /' pop' pares en lugar de 'mov'? –