64ビットアセンブリプログラムでRIP相対アドレッシングを使用する方法

StackOverflow https://stackoverflow.com/questions/3250277

質問

AMD64 ArchtectityのLinuxアセンブリプログラムでRIP相対アドレッシングを使用する方法 AMD64 RIP相対的なアドレス指定モードを使用する簡単な例(Hello World Program)を探しています。

次の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 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はアドレス0x400096であるLEA命令の後にアドレス17バイトをロードし、そこでHello World Stringを見つけることができ、したがってポジションに依存しないコードが得られます。

役に立ちましたか?

解決

あなたはあなたの文字列の address %rsiにロードしたいと思います。あなたのコードは、住所自体ではなくそのアドレスからクワッドワードをロードしようとします。あなたが望む:

lea msg(%rip), %rsi
.

私が間違えていないのなら。テストするためのLinuxボックスがありません。

他のヒント

%RSIのMSGのアドレスが必要なので、置き換えます:

mov msg(%rip),%rsi
.

lea msg(%rip),%rsi
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top