代表的なレジスター
レジスターはCPU内部の高速な記憶場所です。raxは計算結果やシステムコール番号、rdi~rdxは引数、rspはスタックの位置に使われます。
| 名前 | 用途の例 |
|---|---|
rax | 計算結果、システムコール番号 |
rdi | 第1引数、終了コード |
rsi | 第2引数、アドレス |
rdx | 第3引数、データ長 |
rsp | スタックの現在位置 |
movで値を移動する
movは元の値を消さず、コピー先へ値を置きます。レジスター間や定数からの移動に使います。
レジスター間のコピーASSEMBLY
mov rax, 8
mov rbx, rax
add rbx, 4
; raxは8、rbxは12メモリーを読み書きする
ラベルはデータのアドレスを表します。角かっこを付けると、そのアドレスにある値を読み書きします。
数値を更新するASSEMBLY
section .data
number dq 42
section .text
mov rax, [number]
add rax, 8
mov [number], raxdbは1バイト、dqは8バイトを確保します。mov rsi, messageはアドレス、mov al, [message]は先頭の値です。
アドレス計算とエンディアン
角かっこの中には基底レジスター、インデックス、倍率、変位を組み合わせて書けます。x86-64は多バイト整数を下位バイトから並べるリトルエンディアンなので、GDBでメモリーを調べるときは表示順にも注意します。
memory.asmASSEMBLY
section .data
scores dq 70, 85, 92
number dq 42
section .text
global _start
_start:
mov rcx, 2
mov rax, [scores + rcx * 8]
mov rdi, rax
mov rax, 60
syscallビルドCOMMAND
nasm -f elf64 memory.asm -o memory.o
ld memory.o -o memory実行結果OUTPUT
echo $?
92GDBでバイト順を確認COMMAND / OUTPUT
gdb ./memory
(gdb) x/8xb &number
0x...: 0x2a 0x00 0x00 0x00 0x00 0x00 0x00 0x00number dq 42の42は16進数で0x2aです。最も下位のバイト0x2aが低いアドレスに置かれるため、これがリトルエンディアンの並びです。
配列の要素を読む
8バイト単位の配列ASSEMBLY
section .data
scores dq 70, 85, 92
section .text
mov rax, [scores]
mov rbx, [scores + 8]
add rax, rbx
; rax = 155実行結果OUTPUT
70 + 85 = 1551要素が8バイトなので、2番目の要素には+ 8でアクセスします。データのサイズとアドレスの計算を揃えましょう。
