Làm cách nào để sử dụng RIP Relative Addressing trong một chương trình lắp ráp Linux cho kiến trúc AMD64? Tôi đang tìm một ví dụ đơn giản (một chương trình Hello world) sử dụng chế độ địa chỉ liên quan đến AMD64 RIP.Làm thế nào để sử dụng RIP Relative Addressing trong một chương trình lắp ráp 64 bit?
Ví dụ chương trình lắp ráp 64-bit sau sẽ làm việc với bình thường (địa chỉ tuyệt đối):
.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"
Tôi đoán rằng cùng một chương trình sử dụng RIP Relative Addressing sẽ là một cái gì đó như:
.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"
Phiên bản bình thường chạy tốt khi được biên soạn với:
as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
Nhưng tôi không thể làm việc với phiên bản RIP.
Bất kỳ ý tưởng nào?
--- chỉnh sửa ----
Câu trả lời của Stephen Canon làm cho phiên bản RIP hoạt động.
Bây giờ khi tôi tháo rời thực thi của phiên bản RIP tôi nhận được:
objdump -d chào
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)
nào cho thấy những gì tôi đang cố gắng để hoàn thành: lea 0x10 (% rip),% rsi nạp địa chỉ 17 byte sau lệnh lea là địa chỉ 0x400096 nơi chuỗi Hello world có thể được tìm thấy và do đó dẫn đến mã độc lập vị trí.
Tại sao 17 byte sau (0x10 là 16)? – fadedbee
https://www.tortall.net/projects/yasm/manual/html/nasm-effaddr.html nói: 'RIP là thanh ghi chỉ dẫn con trỏ, có chứa địa chỉ của vị trí ngay lập tức theo hướng dẫn hiện tại' nhưng' Lệnh lea' dài 7 byte, không phải là một. – fadedbee
Tại sao cặp 'push' /' pop' thay vì 'mov'? –