0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

x86_64 プログラミング

Last updated at Posted at 2022-08-01

arm64: arm64 プログラミング

文法

構文

AT&T

sub $0x8, %rsp
  • % がついていればAT&T。
  • 右オペランドに代入される。
  • gdbobjdump -d はこの出力
  • GCCのインラインアセンブラでも使える

Intel

sub rsp, 8
  • 左オペランドに代入される。
  • libcapstoneではこちらが使われていそう。
  • objdump -M intel -d するとこっちが出せる。
  • gdb でも set disassembly-flavor intel すると使える。

メモリアクセス

AT&T

mov 0x10(%rbx), %r15

括弧 ( ) がつくとメモリアクセスになる。括弧の前の数字がオフセットになっており、この場合は RBX + 16 の位置がアクセスされている。

Intel

mov DWORD PTR [ebx], 2

という感じで書くらしい。size directiveを指定しない場合は推論される。

レジスタ

Registers in x86 Assembly を見た方が良い。

  • rax : 汎用レジスタ
  • rbx : 汎用レジスタ
  • rcx : 汎用レジスタ
  • rdx : 汎用レジスタ
  • rsi : 汎用レジスタ
  • rdi : 汎用レジスタ
  • rbp : 汎用レジスタ
  • rsp : 汎用レジスタ兼スタックポインタ
  • r8 : 汎用レジスタ
  • r9 : 汎用レジスタ
  • r9 : 汎用レジスタ
  • r10 : 汎用レジスタ
  • r11 : 汎用レジスタ
  • r12 : 汎用レジスタ
  • r13 : 汎用レジスタ
  • r14 : 汎用レジスタ
  • r15 : 汎用レジスタ
  • rip : プログラムカウンタ
  • eflags : フラグレジスタ
  • cs : セグメントレジスタ
  • ss : セグメントレジスタ
  • ds : セグメントレジスタ
  • es : セグメントレジスタ
  • fs : セグメントレジスタ
  • gs : セグメントレジスタ

プレフィックス

  • e: 32bit (例: %eax)
  • r: 64bit (例: %rax)

スタック関連

  • %rbp: ベースポインタ。元のスタックポインタが入っている
  • %rsp: スタックポインタ。デクリメントしてスタックを拡張する。

関数呼び出し

x86_64 で用いられる呼び出し規約は2種類ある。

  • System V AMD64 ABI: Linux, macOS, FreeBSD, Solaris
  • Microsoft x64 calling convention: Windows

System V AMD64 ABI

  • 引数:
    • 整数, ポインタ: RDI, RSI, RDX, RCX, R8, R9
    • 不動小数点: XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7
    • 残りはスタック。右から左にスタックに積む。
  • 返り値:
    • 整数64ビットまで: RAX
    • 整数128ビットまで: RAX & RDX
    • 不動小数点: XMM0 & XMM1
  • caller/callee-save
    • RBX, RSP, RBP, R12–R15: non-volatile (= callee save)
    • RAX, RCX, RDX, RSI, RDI, R8-R11, XMM0-XMM15, YMM0-YMM15, ZMM0-ZMM31: volatile (= caller save)
  • システムコールでは RCX の代わりに R10 を使用

命令

cmp命令

ステータスフラグ ZF, CF を更新する。

命令サフィックス

  • b: 1バイト (8bit)
  • w: 2バイト (16bit)
  • l: 4バイト (32bit)
  • q: 8バイト (64bit)

メモリをオペランドに取るときは必ずサフィックスが必要。

開発環境

実行方法

Intel構文を使いたい場合は .intel_syntax noprefix を書く。

a.s
.globl main
main:
    mov $0, %rax
    ret
$ gcc a.s
$ ./a.out

gdb

レジスタの値を見る

p/x $rdi

などすると %rdi がhexで見れる。 *(void **)($rsp + 0x10) とすると 0x10(%rsp) が見れる。

アセンブリレイアウト

  • layout src: Cのソース
  • layout split: Cのソース + アセンブリ
  • layout asm: アセンブリ
  • layout regs: レジスタ + Cのソース or アセンブリ (直前のlayoutに依存)

C-x o でウィンドウ切り替えで、↑↓でスクロール。C-x a で閉じたり入ったりできる。

objdump

asmを眺める

objdump -d a.o

.text が出てくる。

デバッグ情報を混ぜる

objdump -dS a.o
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?