x86 64_命令とディレクティブ一覧表 - GawinGowin/libasm GitHub Wiki

x86-64 命令とディレクティブ一覧表

このドキュメントは、x86-64アセンブリで使用される命令とディレクティブを網羅的にまとめたものです。

アセンブリディレクティブ

セクション指定

ディレクティブ 意味 用途
section .text テキストセクション 実行可能コード領域
section .data データセクション 初期化済みデータ領域
section .bss BSSセクション 未初期化データ領域
section .rodata 読み取り専用データ 定数データ領域

シンボル可視性

ディレクティブ 意味 用途
global グローバルシンボル宣言 外部から参照可能にする
extern 外部シンボル宣言 他のファイルのシンボルを参照
local ローカルシンボル宣言 ファイル内でのみ参照可能

データ定義

ディレクティブ サイズ 意味
db 1バイト データバイト定義 db 0x41, 'A'
dw 2バイト データワード定義 dw 0x1234
dd 4バイト データダブルワード定義 dd 0x12345678
dq 8バイト データクアッドワード定義 dq 0x123456789ABCDEF0
resb 1バイト バイト領域予約 resb 100
resw 2バイト ワード領域予約 resw 50
resd 4バイト ダブルワード領域予約 resd 25
resq 8バイト クアッドワード領域予約 resq 10

データ移動命令

命令 意味 用途
mov 移動 データをコピー mov rax, rbx
movzx ゼロ拡張移動 小さいサイズからゼロ拡張 movzx rax, bl
movsx 符号拡張移動 小さいサイズから符号拡張 movsx rax, bl
lea 実効アドレス読み込み アドレス計算 lea rax, [rbx + rcx*2]
xchg 交換 2つの値を交換 xchg rax, rbx

スタック操作命令

命令 意味 動作
push プッシュ スタックに値をプッシュ push rax
pop ポップ スタックから値をポップ pop rax
pushf フラグプッシュ フラグレジスタをプッシュ pushf
popf フラグポップ フラグレジスタをポップ popf
pusha 全レジスタプッシュ 全汎用レジスタをプッシュ pusha (32ビットのみ)
popa 全レジスタポップ 全汎用レジスタをポップ popa (32ビットのみ)

算術演算命令

基本算術

命令 意味 動作
add 加算 dest = dest + src add rax, rbx
sub 減算 dest = dest - src sub rax, rbx
mul 乗算(符号なし) rax = rax * operand mul rbx
imul 乗算(符号付き) dest = dest * src imul rax, rbx
div 除算(符号なし) rax = rdx:rax / operand div rbx
idiv 除算(符号付き) rax = rdx:rax / operand idiv rbx
inc インクリメント dest = dest + 1 inc rax
dec デクリメント dest = dest - 1 dec rax
neg 符号反転 dest = -dest neg rax

拡張算術

命令 意味 動作
adc キャリー付き加算 dest = dest + src + CF adc rax, rbx
sbb ボロー付き減算 dest = dest - src - CF sbb rax, rbx

論理演算命令

命令 意味 動作
and 論理積 dest = dest & src and rax, rbx
or 論理和 dest = dest | src or rax, rbx
xor 排他的論理和 dest = dest ^ src xor rax, rbx
not 論理否定 dest = ~dest not rax
test テスト フラグ設定のみ(dest & src) test rax, rbx

シフト・ローテート命令

命令 意味 動作
shl 左シフト 論理左シフト shl rax, 2
shr 右シフト 論理右シフト shr rax, 2
sal 算術左シフト 算術左シフト sal rax, 2
sar 算術右シフト 算術右シフト sar rax, 2
rol 左ローテート 左循環シフト rol rax, 2
ror 右ローテート 右循環シフト ror rax, 2
rcl キャリー付き左ローテート キャリー含む左循環 rcl rax, 2
rcr キャリー付き右ローテート キャリー含む右循環 rcr rax, 2

比較命令

命令 意味 動作
cmp 比較 フラグ設定のみ(dest - src) cmp rax, rbx
test テスト フラグ設定のみ(dest & src) test rax, rax

分岐命令

無条件分岐

命令 意味 動作
jmp ジャンプ 無条件でラベルへジャンプ jmp .loop
call 呼び出し 関数呼び出し call function
ret 復帰 関数から復帰 ret

条件分岐

命令 条件 フラグ 意味
je/jz 等しい/ゼロ ZF=1 等しい場合ジャンプ je .equal
jne/jnz 等しくない/非ゼロ ZF=0 等しくない場合ジャンプ jne .not_equal
jg/jnle より大きい(符号付き) ZF=0 and SF=OF より大きい場合ジャンプ jg .greater
jge/jnl 以上(符号付き) SF=OF 以上の場合ジャンプ jge .greater_equal
jl/jnge より小さい(符号付き) SF≠OF より小さい場合ジャンプ jl .less
jle/jng 以下(符号付き) ZF=1 or SF≠OF 以下の場合ジャンプ jle .less_equal
ja/jnbe より大きい(符号なし) CF=0 and ZF=0 より大きい場合ジャンプ ja .above
jae/jnb 以上(符号なし) CF=0 以上の場合ジャンプ jae .above_equal
jb/jnae より小さい(符号なし) CF=1 より小さい場合ジャンプ jb .below
jbe/jna 以下(符号なし) CF=1 or ZF=1 以下の場合ジャンプ jbe .below_equal
jc キャリーあり CF=1 キャリーフラグセット時ジャンプ jc .carry
jnc キャリーなし CF=0 キャリーフラグクリア時ジャンプ jnc .no_carry
jo オーバーフロー OF=1 オーバーフロー時ジャンプ jo .overflow
jno オーバーフローなし OF=0 オーバーフローなし時ジャンプ jno .no_overflow
js 符号あり(負) SF=1 負の値時ジャンプ js .negative
jns 符号なし(正) SF=0 正の値時ジャンプ jns .positive

ループ命令

命令 意味 動作
loop ループ rcx--, rcx≠0ならジャンプ loop .loop_start
loope/loopz 等しい間ループ rcx--, ZF=1かつrcx≠0ならジャンプ loope .loop_start
loopne/loopnz 等しくない間ループ rcx--, ZF=0かつrcx≠0ならジャンプ loopne .loop_start

文字列操作命令

命令 意味 動作
movs 文字列移動 [rdi] = [rsi], rsi++, rdi++ movsb
cmps 文字列比較 [rsi] - [rdi], rsi++, rdi++ cmpsb
scas 文字列走査 rax - [rdi], rdi++ scasb
lods 文字列読み込み rax = [rsi], rsi++ lodsb
stos 文字列格納 [rdi] = rax, rdi++ stosb

文字列操作の反復プレフィックス

プレフィックス 意味 条件
rep 反復 rcx回繰り返し
repe/repz 等しい間反復 ZF=1の間繰り返し
repne/repnz 等しくない間反復 ZF=0の間繰り返し

フラグ操作命令

命令 意味 動作
clc キャリークリア CF = 0 clc
stc キャリーセット CF = 1 stc
cmc キャリー反転 CF = ~CF cmc
cld 方向フラグクリア DF = 0 cld
std 方向フラグセット DF = 1 std
cli 割り込み禁止 IF = 0 cli
sti 割り込み許可 IF = 1 sti

特殊命令

命令 意味 動作
nop 何もしない プロセッササイクル消費 nop
hlt 停止 プロセッサ停止 hlt
int 割り込み ソフトウェア割り込み int 0x80
syscall システムコール 64ビットシステムコール syscall
sysenter システム入力 高速システムコール入力 sysenter
sysexit システム退出 高速システムコール退出 sysexit

参考:https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/

関数フレーム管理

命令 意味 動作
enter エンタープロローグ スタックフレーム作成 enter 16, 0
leave リープエピローグ スタックフレーム破棄 leave

アドレッシングモード

メモリアドレッシング構文

[base + index*scale + displacement]
要素 説明
base ベースレジスタ rax, rbx, rcx, ...
index インデックスレジスタ rax, rbx, rcx, ... (rsp以外)
scale スケール因子 1, 2, 4, 8
displacement 変位 0x10, -8, label

アドレッシング例

意味
[rax] raxが指すメモリ
[rax + 8] rax + 8が指すメモリ
[rax + rbx] rax + rbxが指すメモリ
[rax + rbx*2] rax + rbx*2が指すメモリ
[rax + rbx*4 + 8] rax + rbx*4 + 8が指すメモリ

データサイズ指定子

指定子 サイズ 意味
byte 8ビット 1バイト操作
word 16ビット 2バイト操作
dword 32ビット 4バイト操作
qword 64ビット 8バイト操作

ラベルとシンボル

ラベルの種類

種類 記法 スコープ
グローバルラベル label: ファイル全体 main:
ローカルラベル .label: 直前のグローバルラベルまで .loop:
数値ラベル 1: 前方・後方参照可能 1:

ラベル参照

記法 意味
label ラベルへの参照 jmp main
1f 次の1:ラベルへ jmp 1f
1b 前の1:ラベルへ jmp 1b

一般的な使用パターン

関数プロローグ・エピローグ

; プロローグ
push rbp
mov rbp, rsp
sub rsp, 16        ; ローカル変数用スペース確保

; エピローグ
mov rsp, rbp       ; または leave
pop rbp
ret

ループパターン

mov rcx, 10        ; カウンタ設定
.loop:
    ; ループ処理
    dec rcx
    jnz .loop      ; rcx != 0 なら繰り返し

条件分岐パターン

cmp rax, rbx
je .equal          ; rax == rbx なら .equal へ
jg .greater        ; rax > rbx なら .greater へ
; else case
jmp .done
.equal:
    ; 等しい場合の処理
    jmp .done
.greater:
    ; 大きい場合の処理
.done: