Assembly

環境構築と基本の書き方

NASMでコードを書き、アセンブル・リンク・実行する流れを体験します。

x86-64 Linux・NASM記法を対象にしています。

Assembly入門の講座一覧

01

対象環境を固定する

AssemblyはCPUごとに命令やシステムコールが異なります。この講座ではx86-64 LinuxとNASM(Intel記法)を使います。ARM64やRISC-Vのコードをそのまま実行できるわけではない点に注意しましょう。

02

NASMとリンカーを準備する

DebianやUbuntu系Linuxでは、次のコマンドで必要なツールを導入できます。

インストールと確認COMMAND
sudo apt update
sudo apt install nasm binutils
nasm -v
ld --version
03

最初のプログラムを動かす

writeで文字列を表示し、exitで終了します。raxへシステムコール番号、rdi以降へ引数を置いてからsyscallを実行します。

hello.asmASSEMBLY
section .data
    message db "Hello, Assembly!", 10
    message_length equ $ - message

section .text
    global _start

_start:
    mov rax, 1
    mov rdi, 1
    mov rsi, message
    mov rdx, message_length
    syscall
    mov rax, 60
    xor rdi, rdi
    syscall
実行COMMAND / OUTPUT
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./hello
Hello, Assembly!
3段階を覚える .asmから.oへ変換するのがアセンブル、実行ファイルへまとめるのがリンクです。
04

命令とラベルを読む

基本形は命令 オペランド1, オペランド2です。Intel記法では代入先を左に書きます。ラベルはジャンプ先やデータの名前になり、;から行末まではコメントです。

計算結果を終了コードで確認ASSEMBLY
section .text
    global _start

_start:
    mov rax, 10
    add rax, 5
    sub rax, 2
    mov rdi, rax
    mov rax, 60
    syscall

echo $?を実行すると、終了コードの13を確認できます。

05

ELFとエラーの読み方

Linuxの実行ファイルはELF形式で、section .textには命令、section .dataには初期値を持つデータを置きます。アセンブル時の「invalid combination of opcode and operands」は命令とオペランドの組み合わせを、リンク時の「undefined reference」はラベル名やglobal指定を確認する合図です。

ファイル形式を確認COMMAND / OUTPUT
file hello
hello: ELF 64-bit LSB executable, x86-64, ...

...は環境によって続く「version 1 (SYSV)」や「statically linked」などを省略しています。

06

練習:終了コードを変える

上のプログラムの数値を変更し、計算結果とecho $?の表示が一致することを確認してください。終了コードは通常0~255の範囲で確認します。