[英]How to use RIP Relative Addressing in a 64-bit assembly program?
How do I use RIP Relative Addressing in a Linux assembly program for the AMD64 archtitecture?如何在 AMD64 架构的 Linux 汇编程序中使用 RIP 相对寻址? I am looking for a simple example (a Hello world program) that uses the AMD64 RIP relative adressing mode.
我正在寻找一个使用 AMD64 RIP 相对寻址模式的简单示例(一个 Hello world 程序)。
For example the following 64-bit assembly program would work with normal (absolute addressing):例如,下面的 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"
I am guessing that the same program using RIP Relative Addressing would be something like:我猜测使用 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"
The normal version runs fine when compiled with:正常版本在编译时运行良好:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
But I can't get the RIP version working.但我无法使 RIP 版本工作。
Any ideas?有任何想法吗?
--- edit ---- - - 编辑 - -
Stephen Canon's answer makes the RIP version work. Stephen Canon 的回答使 RIP 版本有效。
Now when I disassemble the executable of the RIP version I get:现在,当我反汇编 RIP 版本的可执行文件时,我得到:
objdump -d hello 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)
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.这显示了我试图完成的任务:lea 0x10(%rip),%rsi 加载 lea 指令后 17 个字节的地址,该地址是地址 0x400096,可以在其中找到 Hello world 字符串,从而产生 position 独立代码。
I believe that you want to load the address of your string into %rsi
;我相信您想将字符串的地址加载到
%rsi
; your code attempts to load a quadword from that address rather than the address itself.您的代码尝试从该地址而不是地址本身加载四字。 You want:
你要:
lea msg(%rip), %rsi
if I'm not mistaken.如果我没错的话。 I don't have a linux box to test on, however.
但是,我没有要测试的 linux 机器。
Since you need the address of msg in %rsi, just replace:由于您需要 %rsi 中的 msg地址,只需替换:
mov msg(%rip),%rsi
with:和:
lea msg(%rip),%rsi
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.