言語: English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch | Español | Italiano | Русский | العربية
ARM64 に不慣れな読者向け。dyncode コンパイラが生成する命令に焦点を当て、各命令にアノテーションと前後比較を付記。
汎用レジスタ:
x0 ~ x30 64 ビット汎用
w0 ~ w30 対応する下位 32 ビットエイリアス
x29 (fp) フレームポインタ
x30 (lr) リンクレジスタ(戻りアドレスを保持)
sp スタックポインタ(x31 ではない!)
xzr / wzr ゼロレジスタ
特殊レジスタ:
pc プログラムカウンタ(直接書込不可)
Apple ABI 予約:
x16, x17 プラットフォーム予約
x18 TLS ベース(Apple 専用)
呼出規約(AAPCS64):
引数: x0~x7(整数), d0~d7(浮動小数点)
戻り値: x0(整数), d0(浮動小数点)
callee 保存:x19~x28, x29, x30, sp
caller 保存:x0~x18, d0~d31
レッドゾーン:sp 下 128 バイト
b label— 無条件分岐(PC 相対 ±128MB)bl label— リンク付き分岐(imm26 → ARM64_RELOC_BRANCH26 生成)- dyncode が
blを避ける理由:26 ビット即値オフセットにリンカが埋める。外部シンボルでは reloc が発生。blrで代替必須。 br xN/blr xN— レジスタ間接分岐/呼出ret—br lr相当
adr(±1MB)と adrp + add(±4GB ページ整列)。x86_64 の lea rax, [rip + _sym] 相当だが 2 命令に分割。
mov + movk シーケンスで 64 ビット値構築。Data2TextPass の核心:定数データを mov/movk シーケンスとしてスタックに格納。
ldr/str、ldp/stp(ペアロード/ストア)、プレインデックス・ポストインデックスアドレッシング。
add、sub、and、orr、eor、lsr、lsl。
cmp + 条件分岐 (b.eq、b.ne、b.lt、b.gt)、条件選択 (csel)。
純計算 add、再帰フィボナッチ、文字列のスタックインライン化(Data2TextPass)、システムコール(SyscallStubPass 直接 svc)を含む。
全命令列が __TEXT,__text 内に 100% 収まる — これが「真の dyncode」。
| 概念 | x86_64 相当 | ARM64 | DynCode 注記 |
|---|---|---|---|
| 関数呼出 | call rel32 |
bl imm26 |
intra-section: 抽出器が BRANCH26 パッチ |
| アドレスロード | lea rax, [rip+sym] |
adrp+add |
intra-section: PAGE21/PAGEOFF12 パッチ |
| 64 ビット即値 | mov rax, imm64 |
mov+movk ×4 |
reloc なし、Data2TextPass 核心 |
| プロローグ | push rbp; mov rbp,rsp |
stp x29,x30,[sp,#-16]! |
1 命令でペア保存 |
| syscall | syscall |
svc #0x80 |
Darwin BSD: x16=nr, x0~x7=args |