アセンブラ完全ガイド
予約語とオペランド一覧表
データ移動命令
予約語 |
オペランド形式 |
説明 |
使用例 |
mov |
dest, src |
データを移動/コピー |
mov rax, 5 |
movsx |
dest, src |
符号拡張付き移動 |
movsx rax, al |
movzx |
dest, src |
ゼロ拡張付き移動 |
movzx rax, al |
lea |
dest, [addr] |
実効アドレスを読み込み |
lea rax, [rbx+8] |
xchg |
op1, op2 |
二つの値を交換 |
xchg rax, rbx |
算術演算命令
予約語 |
オペランド形式 |
説明 |
使用例 |
add |
dest, src |
加算 |
add rax, 10 |
sub |
dest, src |
減算 |
sub rax, rbx |
mul |
src |
符号なし乗算 |
mul rbx |
imul |
dest, src または src |
符号付き乗算 |
imul rax, 5 |
div |
src |
符号なし除算 |
div rbx |
idiv |
src |
符号付き除算 |
idiv rcx |
inc |
dest |
インクリメント |
inc rax |
dec |
dest |
デクリメント |
dec rbx |
neg |
dest |
符号反転 |
neg rax |
ビット演算命令
予約語 |
オペランド形式 |
説明 |
使用例 |
and |
dest, src |
論理積 |
and rax, 0xFF |
or |
dest, src |
論理和 |
or rax, rbx |
xor |
dest, src |
排他的論理和 |
xor rax, rax |
not |
dest |
ビット反転 |
not rax |
shl |
dest, count |
左シフト |
shl rax, 2 |
shr |
dest, count |
右シフト(論理) |
shr rax, 1 |
sar |
dest, count |
右シフト(算術) |
sar rax, 3 |
rol |
dest, count |
左ローテート |
rol rax, 4 |
ror |
dest, count |
右ローテート |
ror rax, 2 |
比較・テスト命令
予約語 |
オペランド形式 |
説明 |
使用例 |
cmp |
op1, op2 |
比較(減算結果でフラグ設定) |
cmp rax, 10 |
test |
op1, op2 |
テスト(AND結果でフラグ設定) |
test rax, rax |
条件分岐命令
予約語 |
オペランド形式 |
条件 |
説明 |
使用例 |
je / jz
|
label |
ZF=1 |
等しい/ゼロ |
je equal |
jne / jnz
|
label |
ZF=0 |
等しくない/非ゼロ |
jne not_equal |
jg / jnle
|
label |
ZF=0 and SF=OF |
より大きい(符号付き) |
jg greater |
jge / jnl
|
label |
SF=OF |
以上(符号付き) |
jge greater_equal |
jl / jnge
|
label |
SF≠OF |
より小さい(符号付き) |
jl less |
jle / jng
|
label |
ZF=1 or SF≠OF |
以下(符号付き) |
jle less_equal |
ja / jnbe
|
label |
CF=0 and ZF=0 |
より大きい(符号なし) |
ja above |
jae / jnb
|
label |
CF=0 |
以上(符号なし) |
jae above_equal |
jb / jnae
|
label |
CF=1 |
より小さい(符号なし) |
jb below |
jbe / jna
|
label |
CF=1 or ZF=1 |
以下(符号なし) |
jbe below_equal |
jc |
label |
CF=1 |
キャリーフラグセット |
jc carry_set |
jnc |
label |
CF=0 |
キャリーフラグクリア |
jnc no_carry |
jo |
label |
OF=1 |
オーバーフロー |
jo overflow |
jno |
label |
OF=0 |
オーバーフローなし |
jno no_overflow |
js |
label |
SF=1 |
符号フラグセット |
js negative |
jns |
label |
SF=0 |
符号フラグクリア |
jns positive |
無条件分岐・制御命令
予約語 |
オペランド形式 |
説明 |
使用例 |
jmp |
label または addr |
無条件ジャンプ |
jmp start |
call |
label または addr |
関数呼び出し |
call function |
ret |
なし または imm16 |
関数から戻る |
ret |
loop |
label |
RCXをデクリメントして条件ジャンプ |
loop loop_start |
loope / loopz
|
label |
等しい間ループ |
loope equal_loop |
loopne / loopnz
|
label |
等しくない間ループ |
loopne not_equal_loop |
スタック操作命令
予約語 |
オペランド形式 |
説明 |
使用例 |
push |
src |
スタックにプッシュ |
push rax |
pop |
dest |
スタックからポップ |
pop rbx |
pushf / pushfq
|
なし |
フラグレジスタをプッシュ |
pushfq |
popf / popfq
|
なし |
フラグレジスタをポップ |
popfq |
pusha / pushad
|
なし |
全汎用レジスタをプッシュ |
pushad |
popa / popad
|
なし |
全汎用レジスタをポップ |
popad |
文字列操作命令
予約語 |
オペランド形式 |
説明 |
使用例 |
movs |
なし |
文字列移動 |
movsb |
stos |
なし |
文字列格納 |
stosb |
lods |
なし |
文字列読み込み |
lodsb |
scas |
なし |
文字列検索 |
scasb |
cmps |
なし |
文字列比較 |
cmpsb |
rep |
prefix |
反復プリフィックス |
rep movsb |
repe / repz
|
prefix |
等しい間反復 |
repe cmpsb |
repne / repnz
|
prefix |
等しくない間反復 |
repne scasb |
システム制御命令
予約語 |
オペランド形式 |
説明 |
使用例 |
nop |
なし |
何もしない |
nop |
hlt |
なし |
ハルト(停止) |
hlt |
int |
imm8 |
割り込み |
int 0x80 |
iret / iretq
|
なし |
割り込みから戻る |
iretq |
cli |
なし |
割り込み禁止 |
cli |
sti |
なし |
割り込み許可 |
sti |
cld |
なし |
方向フラグクリア |
cld |
std |
なし |
方向フラグセット |
std |
clc |
なし |
キャリーフラグクリア |
clc |
stc |
なし |
キャリーフラグセット |
stc |
条件設定命令
予約語 |
オペランド形式 |
条件 |
説明 |
使用例 |
sete / setz
|
dest |
ZF=1 |
等しければ1を設定 |
sete al |
setne / setnz
|
dest |
ZF=0 |
等しくなければ1を設定 |
setne bl |
setg / setnle
|
dest |
ZF=0 and SF=OF |
より大きければ1を設定 |
setg cl |
setl / setnge
|
dest |
SF≠OF |
より小さければ1を設定 |
setl dl |
浮動小数点命令(x87 FPU)
予約語 |
オペランド形式 |
説明 |
使用例 |
fld |
src |
浮動小数点数をロード |
fld qword [rax] |
fst |
dest |
浮動小数点数を格納 |
fst dword [rbx] |
fstp |
dest |
格納してポップ |
fstp qword [rcx] |
fadd |
src または st(i) |
加算 |
fadd st(1) |
fsub |
src または st(i) |
減算 |
fsub dword [rax] |
fmul |
src または st(i) |
乗算 |
fmul st(2) |
fdiv |
src または st(i) |
除算 |
fdiv qword [rbx] |
SSE命令(一部)
予約語 |
オペランド形式 |
説明 |
使用例 |
movss |
dest, src |
単精度浮動小数点移動 |
movss xmm0, xmm1 |
movsd |
dest, src |
倍精度浮動小数点移動 |
movsd xmm0, [rax] |
addss |
dest, src |
単精度加算 |
addss xmm0, xmm1 |
addsd |
dest, src |
倍精度加算 |
addsd xmm0, [rbx] |
subss |
dest, src |
単精度減算 |
subss xmm0, xmm1 |
mulss |
dest, src |
単精度乗算 |
mulss xmm0, xmm1 |
divss |
dest, src |
単精度除算 |
divss xmm0, xmm1 |
アセンブラの使い方
1. 基本的な文法
; コメントはセミコロンで開始
label: ; ラベル定義
instruction operand1, operand2 ; 命令
2. セクション定義
.section .data ; データセクション
variable: .quad 100 ; 64ビット変数
string: .ascii "Hello" ; 文字列
.section .bss ; 未初期化データセクション
buffer: .space 256 ; 256バイトのバッファ
.section .text ; コードセクション
.global _start ; エントリーポイント
_start:
; プログラム開始
3. データ型定義
疑似命令 |
サイズ |
説明 |
使用例 |
.byte |
1バイト |
バイトデータ |
.byte 0x41 |
.word |
2バイト |
ワードデータ |
.word 1000 |
.dword / .long
|
4バイト |
ダブルワード |
.dword 100000 |
.qword / .quad
|
8バイト |
クワッドワード |
.quad 1000000000 |
.ascii |
可変 |
ASCII文字列 |
.ascii "Hello" |
.asciz / .string
|
可変 |
NULL終端文字列 |
.asciz "World" |
.space / .skip
|
可変 |
未初期化領域 |
.space 100 |
4. 実践例
基本的なプログラム構造
.section .data
msg: .asciz "Hello, World!\n"
msg_len = . - msg - 1
.section .text
.global _start
_start:
; write システムコール
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, msg ; メッセージのアドレス
mov rdx, msg_len ; メッセージの長さ
syscall ; システムコール実行
; exit システムコール
mov rax, 60 ; sys_exit
mov rdi, 0 ; 終了コード
syscall
ループの実装
.section .text
.global _start
_start:
mov rcx, 10 ; カウンタを10に設定
mov rax, 0 ; 累積値を0に初期化
loop_start:
add rax, rcx ; RAXにRCXを加算
dec rcx ; カウンタをデクリメント
jnz loop_start ; カウンタが0でなければループ継続
; RAXには1+2+3+...+10 = 55が格納される
条件分岐の実装
.section .text
.global _start
_start:
mov rax, 15 ; テスト値
cmp rax, 10 ; 10と比較
jl less_than_10 ; 10未満の場合
je equal_to_10 ; 10と等しい場合
jg greater_than_10 ; 10より大きい場合
less_than_10:
mov rbx, 1 ; 1を設定
jmp end
equal_to_10:
mov rbx, 2 ; 2を設定
jmp end
greater_than_10:
mov rbx, 3 ; 3を設定
end:
; RBXには結果が格納される
関数の実装
.section .text
.global _start
_start:
mov rdi, 5 ; 第1引数
mov rsi, 3 ; 第2引数
call add_function ; 関数呼び出し
; RAXには結果が格納される
mov rdi, rax ; 終了コード
mov rax, 60 ; sys_exit
syscall
add_function:
push rbp ; ベースポインタ保存
mov rbp, rsp ; 新しいフレーム設定
mov rax, rdi ; 第1引数をRAXに
add rax, rsi ; 第2引数を加算
mov rsp, rbp ; スタック復元
pop rbp ; ベースポインタ復元
ret ; 呼び出し元に戻る
5. アセンブル・リンク手順
GASを使用した場合
as -64 program.s -o program.o
ld program.o -o program
./program
NASMを使用した場合
nasm -f elf64 program.asm -o program.o
ld program.o -o program
./program
6. デバッグのコツ
GDBでのデバッグ
as -64 --gstabs program.s -o program.o
ld program.o -o program
gdb ./program
(gdb) break _start
(gdb) run
(gdb) stepi
(gdb) info registers
(gdb) x/10x $rsp
7. よく使われるパターン
レジスタのクリア
xor rax, rax ; RAXを0にクリア(高速)
mov rax, 0 ; RAXを0に設定(通常)
文字列の長さ計算
mov rdi, string ; 文字列のアドレス
mov rcx, -1 ; 最大長
mov al, 0 ; NULL文字
cld ; 前進方向
repne scasb ; NULL文字を検索
not rcx ; 長さを計算
dec rcx ; NULL文字分を除く
メモリのクリア
mov rdi, buffer ; バッファのアドレス
mov rcx, 256 ; クリアするバイト数
xor rax, rax ; 0で埋める
rep stosb ; メモリをクリア
レジスタ一覧
x86-64 汎用レジスタ
64ビット |
32ビット |
16ビット |
8ビット(上位) |
8ビット(下位) |
用途 |
RAX |
EAX |
AX |
AH |
AL |
アキュムレータ |
RBX |
EBX |
BX |
BH |
BL |
ベース |
RCX |
ECX |
CX |
CH |
CL |
カウンタ |
RDX |
EDX |
DX |
DH |
DL |
データ |
RSI |
ESI |
SI |
- |
SIL |
ソースインデックス |
RDI |
EDI |
DI |
- |
DIL |
デスティネーションインデックス |
RSP |
ESP |
SP |
- |
SPL |
スタックポインタ |
RBP |
EBP |
BP |
- |
BPL |
ベースポインタ |
R8 |
R8D |
R8W |
- |
R8B |
汎用レジスタ |
R9 |
R9D |
R9W |
- |
R9B |
汎用レジスタ |
R10 |
R10D |
R10W |
- |
R10B |
汎用レジスタ |
R11 |
R11D |
R11W |
- |
R11B |
汎用レジスタ |
R12 |
R12D |
R12W |
- |
R12B |
汎用レジスタ |
R13 |
R13D |
R13W |
- |
R13B |
汎用レジスタ |
R14 |
R14D |
R14W |
- |
R14B |
汎用レジスタ |
R15 |
R15D |
R15W |
- |
R15B |
汎用レジスタ |
フラグレジスタ(RFLAGS)
ビット |
フラグ |
名称 |
説明 |
0 |
CF |
キャリーフラグ |
演算でキャリー/ボローが発生 |
2 |
PF |
パリティフラグ |
結果の下位8ビットの1の個数が偶数 |
4 |
AF |
補助キャリーフラグ |
BCD演算でキャリーが発生 |
6 |
ZF |
ゼロフラグ |
演算結果が0 |
7 |
SF |
符号フラグ |
演算結果が負 |
8 |
TF |
トラップフラグ |
シングルステップモード |
9 |
IF |
割り込みフラグ |
割り込み許可 |
10 |
DF |
方向フラグ |
文字列操作の方向 |
11 |
OF |
オーバーフローフラグ |
符号付き演算でオーバーフロー |
セグメントレジスタ
レジスタ |
名称 |
用途 |
CS |
コードセグメント |
実行中のコード |
DS |
データセグメント |
データアクセス |
ES |
エクストラセグメント |
追加のデータアクセス |
FS |
ファイルセグメント |
スレッドローカルストレージ |
GS |
ジェネラルセグメント |
追加用途 |
SS |
スタックセグメント |
スタック操作 |
浮動小数点レジスタ
x87 FPU レジスタ
- ST(0) - ST(7): 80ビット浮動小数点レジスタスタック
SSE/AVX レジスタ
- XMM0 - XMM15: 128ビット(SSE)
- YMM0 - YMM15: 256ビット(AVX)
- ZMM0 - ZMM31: 512ビット(AVX-512)
アドレッシングモード
即値アドレッシング
mov rax, 100 ; 即値100をRAXに格納
レジスタアドレッシング
mov rax, rbx ; RBXの値をRAXにコピー
直接アドレッシング
mov rax, [1000] ; メモリアドレス1000の値をRAXに読み込み
間接アドレッシング
mov rax, [rbx] ; RBXが指すアドレスの値をRAXに読み込み
ベース+ディスプレースメント
mov rax, [rbx+8] ; RBX+8のアドレスの値を読み込み
ベース+インデックス
mov rax, [rbx+rcx] ; RBX+RCXのアドレスの値を読み込み
ベース+インデックス+スケール
mov rax, [rbx+rcx*2] ; RBX+(RCX*2)のアドレスの値を読み込み
mov rax, [rbx+rcx*4+8] ; RBX+(RCX*4)+8のアドレスの値を読み込み
システムコール(Linux x86-64)
主要なシステムコール
番号 |
名前 |
引数 |
説明 |
0 |
sys_read |
rdi=fd, rsi=buf, rdx=count |
ファイル読み込み |
1 |
sys_write |
rdi=fd, rsi=buf, rdx=count |
ファイル書き込み |
2 |
sys_open |
rdi=filename, rsi=flags, rdx=mode |
ファイルオープン |
3 |
sys_close |
rdi=fd |
ファイルクローズ |
9 |
sys_mmap |
複数の引数 |
メモリマップ |
11 |
sys_munmap |
rdi=addr, rsi=length |
メモリアンマップ |
39 |
sys_getpid |
なし |
プロセスID取得 |
57 |
sys_fork |
なし |
プロセス複製 |
59 |
sys_execve |
rdi=filename, rsi=argv, rdx=envp |
プログラム実行 |
60 |
sys_exit |
rdi=status |
プロセス終了 |
システムコールの使用例
; Hello World を出力
.section .data
msg: .asciz "Hello, World!\n"
msg_len = . - msg - 1
.section .text
.global _start
_start:
; write(1, msg, msg_len)
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, msg ; メッセージ
mov rdx, msg_len ; 長さ
syscall
; exit(0)
mov rax, 60 ; sys_exit
mov rdi, 0 ; 終了ステータス
syscall
アセンブリの読み方・考え方
1. 読み方の基本原則
トップダウン方式
main: ; 1. まずメイン関数を見つける
call setup ; 2. 初期化処理を確認
call process ; 3. メイン処理を確認
call cleanup ; 4. 終了処理を確認
ret
ボトムアップ方式
; 1. 個別の関数から理解していく
multiply:
push rbp
mov rbp, rsp
; この関数が何をするか理解
pop rbp
ret
; 2. それらがどう組み合わされるか把握
2. 読み方の手順
ステップ1: 全体構造の把握
.section .data ; データ領域を確認
.section .bss ; 未初期化領域を確認
.section .text ; コード領域を確認
ステップ2: エントリーポイントの特定
.global _start ; プログラムの開始点
_start:
; ここから実行が始まる
ステップ3: データ構造の理解
.section .data
array: .quad 1, 2, 3, 4, 5 ; 配列
counter: .long 0 ; カウンタ変数
message: .asciz "Hello" ; 文字列
ステップ4: 制御フローの追跡
cmp rax, 0 ; 比較
je zero_case ; 条件分岐
jmp normal_case ; 無条件分岐
3. 考え方のコツ
レジスタの役割を意識する
; x86-64の一般的な使い方
mov rdi, arg1 ; 第1引数
mov rsi, arg2 ; 第2引数
mov rdx, arg3 ; 第3引数
call function ; 関数呼び出し
mov result, rax ; 戻り値を保存
スタックの動きを追跡する
push rbp ; ベースポインタ保存
mov rbp, rsp ; 新しいフレーム作成
sub rsp, 16 ; ローカル変数用領域確保
; 処理...
add rsp, 16 ; スタック復元
pop rbp ; ベースポインタ復元
ret ; 関数終了
メモリレイアウトを意識する
; 高位アドレス
; +--------+
; | 引数 |
; +--------+
; |戻りアドレス|
; +--------+
; |旧RBP | <- RBP
; +--------+
; |ローカル変数|
; +--------+ <- RSP
; 低位アドレス
4. パターン認識
典型的な関数プロローグ
function:
push rbp ; 関数開始の定型文
mov rbp, rsp ; スタックフレーム設定
sub rsp, N ; ローカル変数確保
典型的な関数エピローグ
add rsp, N ; スタック復元
pop rbp ; ベースポインタ復元
ret ; 関数終了の定型文
ループパターンの認識
mov rcx, 10 ; カウンタ初期化
loop_start:
; 処理内容
dec rcx ; カウンタ減算
jnz loop_start ; 条件ループ
条件分岐パターン
cmp rax, rbx ; 比較
jl less_case ; 分岐1
je equal_case ; 分岐2
; else case ; デフォルトケース
アセンブリあるある集
初心者あるある
1. レジスタサイズ混同あるある
; ❌ 混同しがち
mov eax, 0x100000000 ; 32ビットレジスタに64ビット値
mov al, 256 ; 8ビットレジスタに9ビット値
; ✅ 正しい使い方
mov rax, 0x100000000 ; 64ビット値は64ビットレジスタに
mov al, 255 ; 8ビット値は8ビットレジスタに
2. アドレッシングモード間違いあるある
; ❌ よくある間違い
mov rax, 100 ; 即値100をRAXに
mov rbx, rax ; RAXの値をRBXに
mov rcx, [100] ; アドレス100の値をRCXに(混同)
; ✅ 正しい理解
mov rax, 100 ; RAX = 100(即値)
mov rbx, [100] ; RBX = メモリ[100]の値(間接参照)
3. スタック操作忘れあるある
; ❌ スタック不均衡
function:
push rbp
push rbx
; 処理...
pop rbp ; 順序が間違い!
ret
; ✅ 正しいスタック操作
function:
push rbp
push rbx
; 処理...
pop rbx ; 逆順でポップ
pop rbp
ret
中級者あるある
4. フラグレジスタ忘れあるある
; ❌ フラグが上書きされる
cmp rax, 10
mov rbx, 5 ; movはフラグに影響しない(OK)
add rcx, 1 ; addはフラグを変更!(危険)
je equal_case ; 間違ったフラグで判定
; ✅ フラグを意識した書き方
cmp rax, 10
je equal_case ; 比較直後に分岐
5. 関数呼び出し規約混同あるある
; ❌ System V ABIとWindows ABIの混同
; System V (Linux): RDI, RSI, RDX, RCX, R8, R9
; Windows x64: RCX, RDX, R8, R9
; 環境を意識した呼び出し
6. オーバーフロー軽視あるある
; ❌ オーバーフローチェック忘れ
add rax, rbx
; オーバーフローしたらどうなる?
; ✅ オーバーフロー対策
add rax, rbx
jo overflow_handler ; オーバーフローをチェック
上級者あるある
7. 最適化の逆効果あるある
; ❌ 過度な最適化で可読性低下
xor rax, rax ; RAX = 0(高速だが分かりにくい)
lea rbx, [rax+1] ; RBX = 1(トリッキー)
; ✅ 適度な最適化
mov rax, 0 ; 明確
mov rbx, 1 ; 理解しやすい
8. アラインメント問題あるある
; ❌ アラインメントを考慮しない
.section .data
char_val: .byte 1
int_val: .long 100 ; 4バイト境界に来ない可能性
; ✅ アラインメントを意識
.section .data
char_val: .byte 1
.align 4 ; 4バイト境界に調整
int_val: .long 100
9. キャッシュライン意識あるある
; CPUキャッシュを意識したデータ配置
.section .data
.align 64 ; キャッシュライン境界
hot_data: ; 頻繁にアクセスするデータ
.quad 1, 2, 3, 4
cold_data: ; あまり使わないデータ
.quad 100, 200, 300, 400
デバッグあるある
10. セグメンテーションフォルト頻発あるある
; ❌ よくあるSegFaultの原因
mov rax, 0
mov [rax], 100 ; NULL pointer dereference
mov rsp, 0x1000 ; 不正なスタックポインタ
ret ; クラッシュ
; ✅ 安全なメモリアクセス
cmp rax, 0
je null_check ; NULLチェック
mov [rax], 100
11. 無限ループ作成あるある
; ❌ 終了条件ミス
mov rcx, 10
loop_start:
; 処理...
inc rcx ; カウンタを増加(間違い)
cmp rcx, 0
jne loop_start ; 永続ループ
; ✅ 正しいループ
mov rcx, 10
loop_start:
; 処理...
dec rcx ; カウンタを減少
jnz loop_start ; ゼロでなければ継続
プロあるある
12. コンパイラ出力解読あるある
; コンパイラが生成したコード
lea rax, [rdi+rdi*2] ; RAX = RDI * 3(効率的な乗算)
sal rdi, 2 ; RDI = RDI * 4(左シフト)
13. インラインアセンブリ落とし穴あるある
asm volatile ("mov %1, %0"
: "=r" (output)
: "r" (input)
: "memory");
14. アーキテクチャ依存コードあるある
; x86特有の命令(他のアーキテクチャでは動かない)
bswap rax ; バイトスワップ(x86のみ)
xlat ; テーブル参照変換(x86のみ)
現実世界のあるある
15. デバッガとの格闘あるある
(gdb) x/10x $rsp
(gdb) info registers
(gdb) disas main
16. パフォーマンス測定あるある
; 測定用のコード挿入
rdtsc ; タイムスタンプカウンタ読み取り
mov r15, rax ; 開始時刻保存
; 測定対象の処理
rdtsc ; 終了時刻
sub rax, r15 ; 経過サイクル計算
17. リバースエンジニアリングあるある
; よく見かける最適化パターン
test rax, rax ; raxが0かチェック(cmp rax, 0と同じ)
jz zero_case ; ゼロなら分岐
xor rax, rax ; rax = 0(mov rax, 0より短い)
トラブルシューティング
よくあるエラーと対策
エラー |
原因 |
対策 |
Segmentation fault |
不正メモリアクセス |
NULLチェック、境界チェック |
Stack overflow |
スタック溢れ |
再帰深度制限、局所変数削減 |
Illegal instruction |
未対応命令 |
CPUサポート確認 |
Bus error |
アラインメント違反 |
データ境界調整 |
デバッグ手法
; デバッグ用の仕込み
debug_print:
push rax
push rdi
push rsi
push rdx
; レジスタ値を出力
pop rdx
pop rsi
pop rdi
pop rax
ret
このガイドを参考に、アセンブラプログラミングの基本から応用、そして現実的な問題まで習得できます。実際のプログラミングでは、使用するアーキテクチャ(x86-64、ARM、RISC-V等)に応じて命令セットが異なることに注意してください。
Discussion