x86アーキテクチャ入門
はじめに
x86は、現代のPCやサーバーで最も広く使用されているアーキテクチャです。この記事では、x86の基本概念からアセンブリプログラミングの基礎まで解説します。
x86の歴史と特徴
歴史
- 1978年: Intel 8086(16ビット)登場
- 1985年: 80386(32ビット、IA-32)登場
- 2003年: AMD64/x86-64(64ビット)登場
特徴
- CISCアーキテクチャ: 複雑な命令セット
- 可変長命令: 1バイト〜15バイト
- 豊富なアドレッシングモード: メモリ操作の柔軟性
- 後方互換性: 古いコードの実行が可能
レジスタ
汎用レジスタ(64ビット)
| 64ビット | 32ビット | 16ビット | 8ビット | 用途 |
|---|---|---|---|---|
| RAX | EAX | AX | AL | アキュムレータ |
| RBX | EBX | BX | BL | ベース |
| RCX | ECX | CX | CL | カウンタ |
| RDX | EDX | DX | DL | データ |
| RSI | ESI | SI | SIL | ソースインデックス |
| RDI | EDI | DI | DIL | デスティネーション |
| RSP | ESP | SP | SPL | スタックポインタ |
| RBP | EBP | BP | BPL | ベースポインタ |
| R8-R15 | R8D-R15D | R8W-R15W | R8B-R15B | 拡張レジスタ |
特殊レジスタ
- RIP: 命令ポインタ
- RFLAGS: 状態フラグ
- セグメントレジスタ: CS, DS, ES, FS, GS, SS
基本命令
データ転送
HLJSASM
mov rax, 42 ; 即値をロード
mov rbx, rax ; レジスタ間転送
mov rax, [rbx] ; メモリからロード
mov [rbx], rax ; メモリへストア
算術演算
HLJSASM
add rax, rbx ; rax = rax + rbx
sub rax, rbx ; rax = rax - rbx
imul rax, rbx ; rax = rax * rbx
xor rdx, rdx
div rbx ; rax = rdx:rax / rbx
制御フロー
HLJSASM
cmp rax, rbx ; 比較
je label ; 等しければジャンプ
jne label ; 等しくなければジャンプ
jl label ; 小さければジャンプ
jg label ; 大きければジャンプ
jmp label ; 無条件ジャンプ
call function ; 関数呼び出し
ret ; 戻り
関数呼び出し規約(System V AMD64 ABI)
引数渡し
| 順序 | 整数/ポインタ | 浮動小数点 |
|---|---|---|
| 第1引数 | RDI | XMM0 |
| 第2引数 | RSI | XMM1 |
| 第3引数 | RDX | XMM2 |
| 第4引数 | RCX | XMM3 |
| 第5引数 | R8 | XMM4 |
| 第6引数 | R9 | XMM5 |
| 以降 | スタック | スタック |
戻り値
- 整数/ポインタ: RAX
- 浮動小数点: XMM0
呼び出し側保存レジスタ
- Caller-saved: RAX, RCX, RDX, RSI, RDI, R8-R11
- Callee-saved: RBX, RBP, R12-R15
実践:Hello World
HLJSASM
section .data
msg db "Hello, x86!", 10
len equ $ - msg
section .text
global _start
_start:
; write(1, msg, len)
mov rax, 1 ; syscall: write
mov rdi, 1 ; fd: stdout
mov rsi, msg ; buffer
mov rdx, len ; length
syscall
; exit(0)
mov rax, 60 ; syscall: exit
xor rdi, rdi ; status: 0
syscall
ビルドと実行
HLJSBASH
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello
まとめ
x86アーキテクチャは歴史が長く、複雑ですが、現代のシステムプログラミングには不可欠です。レジスタ、命令セット、呼び出し規約を理解することで、効率的な低レイヤープログラミングが可能になります。