Assembly

デバッグと練習問題

命令の前後で状態を確認し、ここまでの知識を小さな問題で定着させます。

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

Assembly入門の講座一覧

01

GDBで変化を追う

Assemblyでは、命令の前後でレジスターとメモリーがどう変わったかを確認します。

基本操作COMMAND
gdb ./hello
(gdb) break _start
(gdb) run
(gdb) info registers rax rdi rsi rdx
(gdb) stepi
(gdb) x/s $rsi
(gdb) quit
02

練習問題

問題1:3つの数の合計

4、7、9の合計を終了コードで返してください。

解答例ASSEMBLY
mov rax, 4
add rax, 7
add rax, 9
mov rdi, rax
mov rax, 60
syscall
実行結果OUTPUT
echo $?
20
問題2:偶数かどうか

test rax, 1を使い、偶数なら0、奇数なら1を返してください。

解答例ASSEMBLY
mov rax, 14
test rax, 1
jnz odd
xor rdi, rdi
jmp finish
odd:
mov rdi, 1
finish:
mov rax, 60
syscall
実行結果OUTPUT
echo $?
0
問題3:配列の最大値

12、5、21、9をループで比較し、最大値を返してください。

解答例ASSEMBLY
scores dq 12, 5, 21, 9
mov rax, [scores]
mov rcx, 1
find_max:
cmp rcx, 4
jge finish
mov rbx, [scores + rcx * 8]
cmp rbx, rax
jle next
mov rax, rbx
next:
inc rcx
jmp find_max
finish:
mov rdi, rax
mov rax, 60
syscall
実行結果OUTPUT
echo $?
21
問題4:安全な割り算

割る値が0なら中止し、0でなければ23 / 5の商を返してください。

解答例ASSEMBLY
mov rax, 23
mov rbx, 5
cmp rbx, 0
je error
xor rdx, rdx
div rbx
mov rdi, rax
jmp finish
error:
mov rdi, 1
finish:
mov rax, 60
syscall
実行結果OUTPUT
echo $?
4
問題5:文字列の長さ

終端の0まで1バイトずつ調べ、Helloの長さを返してください。

解答例ASSEMBLY
message db "Hello", 0
mov rsi, message
xor rcx, rcx
count:
cmp byte [rsi + rcx], 0
je finish
inc rcx
jmp count
finish:
mov rdi, rcx
mov rax, 60
syscall
実行結果OUTPUT
echo $?
5
進め方 まず各レジスターの値を紙に書き、最小のソースを実行します。失敗したらエラー全文を読み、GDBで直前の命令を確認しましょう。
03

次に学ぶこと

数字の文字列変換、ファイル入出力、C言語との連携、ELF形式、呼び出し規約、SIMD命令へ進めます。常にCPU・OS・アセンブラーを確認する習慣を持ちましょう。