如何使用RIP相对寻址的64位汇编程序? [英] How to use RIP Relative Addressing in a 64-bit assembly program?

查看:2722
本文介绍了如何使用RIP相对寻址的64位汇编程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何使用RIP相对寻址在Linux汇编程序的AMD64 archtitecture? 我要寻找一个简单的例子(一个Hello World程序),采用AMD64 RIP相对adressing模式。

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!\n"

我猜测,使用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!\n"

普通版在编译时运行正常:

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.

任何想法?

---编辑----

--- edit ----

斯蒂芬佳能的回答使得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加载地址17字节lea指令这是地址0x400096那里的世界,你好字符串可以发现,从而导致位置无关的$ C后, $ C。

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.

推荐答案

我相信,你要加载的地址的字符串的到%RSI ;您的code试图从该地址,而不是地址本身加载一个四字。你想:

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.

这篇关于如何使用RIP相对寻址的64位汇编程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆