Write システムコール (1)
CoddyのAssemblyジャーニー「基礎」セクションの一部 — レッスン 35/45。
プログラムを終了する方法はすでに知っています。しかし、黙って終了するのはあまり役に立ちません。ユーザーが何かを確認できるように、プログラムに出力を表示させたいはずです。
そのためには、writeシステムコールが必要です。
writeシステムコールとは何ですか?
writeシステムコールは、テキストを画面に表示する(またはファイルに書き込む)ようオペレーティングシステムに指示します。これは、プログラムが出力を生成するための手段です。
write のシステムコール番号は 1 です。
writeの仕組み:
exitシステムコール(引数が1つだけ必要)とは異なり、writeには3つの引数が必要です:
| 引数 | レジスタ | 役割 | 例 |
|---|---|---|---|
| ファイル記述子 | rdi | 書き込み先 (1 = 画面) | mov rdi, 1 |
| バッファアドレス | rsi | メモリ内のテキストの場所 | mov rsi, message |
| バイト数 | rdx | 出力するバイト数 | mov rdx, 13 |
実行中の write システムコール:
mov rax, 1 ; write のシステムコール番号
mov rdi, 1 ; ファイルディスクリプタ 1 = stdout (画面)
mov rsi, msg ; 表示する文字列のアドレス
mov rdx, 13 ; 表示するバイト数
syscall ; OS に表示を要求する画面にメッセージを表示するには、5行必要です。まず、書き込み(write)のためにシステムコール番号1をraxに入れます。次に、OSに画面へ出力するように伝えるため、1をrdiに入れます。
次に、文字列(msg)のアドレスを rsi に入れます。その後、バイト数(13)を rdx に入れます。最後に、OSに表示を依頼するために syscall を実行します。
write を実行したときに何が起こるか:
- CPU が Linux カーネルにジャンプします
- カーネルは「write syscall」を確認します
rdi(書き込み先)、rsi(テキストの場所)、およびrdx(バイト数)を読み取ります
- テキストを画面に表示します
- プログラムに制御を戻します
文字列と組み合わせてみます:
section .data
msg db 'Hello', 0x0a ; 改行を含む文字列
section .text
global _start
_start:
mov rax, 1 ; writeシステムコール
mov rdi, 1 ; 標準出力
mov rsi, msg ; 文字列のアドレス
mov rdx, 6 ; 長さ (Hello + 改行 = 6バイト)
syscall
mov rax, 60 ; exitシステムコール
mov rdi, 0
syscallこのプログラムは Hello を出力して終了します。
チャレンジ
"Hi" というメッセージとそれに続く改行を出力するプログラムを作成してください。write システムコールを使用してください。
文字列はテストハーネス内ですでに定義されています。システムコールのセットアップを記述するだけです。
自分で試してみよう
section .data
msg db 'Hi', 0x0a
msgLen equ $ - msg
section .text
global _start
_start:
; TODO: msgを表示するためにwriteシステムコールを設定して呼び出す
; rax=1, rdi=1, rsi=msg, rdx=msgLen を使用する
; プログラムを終了する
mov rax, 60
mov rdi, 0
syscallこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。