AMD64 아키텍처의 Linux 어셈블리 프로그램에서 RIP 상대 주소 지정은 어떻게 사용합니까? AMD64 RIP 상대 주소 지정 모드를 사용하는 간단한 예제 (Hello World 프로그램)를 찾고 있습니다.64 비트 어셈블리 프로그램에서 RIP 상대 주소 지정을 사용하는 방법은 무엇입니까?
예를 들면 다음과 같은 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는 상대 주소 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 버전을 사용할 수 없습니다.
아이디어가 있으십니까?
은 --- 편집 ----
스티븐 캐논의 대답은 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)
: 레아은 0x10 (% 립), % RSI를 Hello World 문자열을 찾을 수있는 주소 0x400096 인 lea 명령 다음에 17 바이트의 주소를로드하므로 위치 독립 코드가 생성됩니다.
왜 17 바이트 (0x10은 16)입니까? – fadedbee
https://www.tortall.net/projects/yasm/manual/html/nasm-effaddr.html :'RIP는 현재 명령어 바로 다음 위치의 주소를 포함하는 명령어 포인터 레지스터이지만' lea' 명령은 길이가 7 바이트가 아니라 1 바이트입니다. – fadedbee
왜 '밀기'대신에'밀기'/'팝'한 쌍이 필요한가요? –