対象環境を固定する
AssemblyはCPUごとに命令やシステムコールが異なります。この講座ではx86-64 LinuxとNASM(Intel記法)を使います。ARM64やRISC-Vのコードをそのまま実行できるわけではない点に注意しましょう。
NASMとリンカーを準備する
DebianやUbuntu系Linuxでは、次のコマンドで必要なツールを導入できます。
インストールと確認COMMAND
sudo apt update
sudo apt install nasm binutils
nasm -v
ld --version最初のプログラムを動かす
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へ変換するのがアセンブル、実行ファイルへまとめるのがリンクです。命令とラベルを読む
基本形は命令 オペランド1, オペランド2です。Intel記法では代入先を左に書きます。ラベルはジャンプ先やデータの名前になり、;から行末まではコメントです。
計算結果を終了コードで確認ASSEMBLY
section .text
global _start
_start:
mov rax, 10
add rax, 5
sub rax, 2
mov rdi, rax
mov rax, 60
syscallecho $?を実行すると、終了コードの13を確認できます。
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」などを省略しています。
練習:終了コードを変える
上のプログラムの数値を変更し、計算結果とecho $?の表示が一致することを確認してください。終了コードは通常0~255の範囲で確認します。
