问题描述
如何在用于 AMD64 架构的 Linux 汇编程序中使用 RIP 相对寻址?我正在寻找一个使用 AMD64 RIP 相对寻址模式的简单示例(一个 Hello world 程序).
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.
例如,以下 64 位汇编程序可以正常(绝对寻址)运行:
For example the following 64-bit assembly program would work with normal (absolute addressing):
.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!
"
我猜使用 RIP 相对寻址的同一个程序会是这样的:
I am guessing that the same program using RIP Relative Addressing would be something like:
.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!
"
正常版本在编译时运行良好:
The normal version runs fine when compiled with:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
但我无法使用 RIP 版本.
But I can't get the RIP version working.
有什么想法吗?
--- 编辑----
Stephen Canon 的回答使 RIP 版本有效.
Stephen Canon's answer makes the RIP version work.
现在当我反汇编 RIP 版本的可执行文件时:
Now when I disassemble the executable of the RIP version I get:
objdump -d 你好
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)
这显示了我想要完成的任务:lea 0x10(%rip),%rsi 在 lea 指令之后 17 个字节加载地址,该地址是地址 0x400096,可以在其中找到 Hello world 字符串,从而产生位置无关代码.
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.
推荐答案
我相信您想将字符串的 address 加载到 %rsi
中;您的代码尝试从该地址而不是地址本身加载一个四字.你想要:
I believe that you want to load the address of your string into %rsi
; your code attempts to load a quadword from that address rather than the address itself. You want:
lea msg(%rip), %rsi
如果我没记错的话.但是,我没有可用于测试的 linux 机器.
if I'm not mistaken. I don't have a linux box to test on, however.
这篇关于如何在 64 位汇编程序中使用 RIP 相对寻址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!