如何在64位汇编程序中使用RIP相对寻址?
-
15-09-2020 - |
题
如何在Amd64archtitecture的Linux汇编程序中使用RIP相对寻址?我正在寻找一个简单的例子(一个Hello world程序),它使用AMD64RIP相对adressing模式。
例如,下面的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"
我猜测使用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"
正常版本编译时运行良好:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
但我无法让RIP版本工作。
有什么想法吗?
---编辑 ----
Stephen Canon的回答使RIP版本工作。
现在,当我拆卸RIP版本的可执行文件时,我得到:
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)
这说明了我想完成的任务:lea0x10(%rip),%rsi在lea指令之后加载地址17字节,该地址是地址0x400096,可以在其中找到Hello world字符串,从而产生位置独立的代码。
解决方案
我相信你想装上 地址 你的绳子进入 %rsi
;您的代码尝试从该地址而不是地址本身加载四字。你要:
lea msg(%rip), %rsi
如果我没弄错的话。但是,我没有一个linux盒子来测试。
其他提示
因为您需要msg中的地址%RSI,只需替换:
mov msg(%rip),%rsi
.
:
lea msg(%rip),%rsi
. 不隶属于 StackOverflow