Buffer Address (rsi)
CoddyのAssemblyジャーニー「基礎」セクションの一部。レッスン 37/45。
write システムコールでは、出力先(rdi 内のファイル記述子)を OS に伝えた後、何を出力するかを伝える必要があります。メモリ内の文字列のアドレスを渡すことで、これを行います。
バッファアドレス用のレジスタはrsiです。
バッファとは何ですか?
バッファとは、データを保持するメモリ領域のことです。今回の場合、バッファは出力したい文字列です。
なぜ値そのものではなく、アドレスなのか?
writeシステムコールは、メモリ上のどこから文字列が始まるかを知る必要があります。rdxで指定した長さに達するまで、そのアドレスからバイトを読み取ります。システムコールに実際の文字を送るのではありません。その文字列の場所を送ります。
例:
section .data
msg db 'Hello', 0x0a
section .text
mov rsi, msg ; rsiにはmsgのアドレスが格納されているmsgの正体:
msgはラベルです。アセンブラはこれを数値に置き換えます。その数値は、文字列'Hello'が格納されているメモリアドレスです。mov rsi, msgと書くと、そのアドレスの数値をrsiに入れます。
アドレスを忘れるとどうなりますか?
rsiを設定しないと、レジスタには以前から入っていた不定な値が残ります。OSはランダムなメモリアドレスから読み取ろうとするため、セグメンテーション違反(クラッシュ)が発生する可能性が高くなります。
writeシステムコールを使った完全な例:
section .data
msg db 'Hello', 0x0a
len equ $ - msg
section .text
mov rax, 1 ; write システムコール
mov rdi, 1 ; stdout
mov rsi, msg ; 文字列のアドレス
mov rdx, len ; バイト数
syscallチャレンジ
改行が続く値 'Hi' を持つ、greeting という文字列が与えられています。greeting のアドレスを rsi に読み込むコード行を書いてください。
rsi のための mov 命令だけを書いてください。
自分で試してみよう
section .text
global _start
_start:
%include "solution.asm"
mov rax, 1
mov rdi, 1
; rsi にはすでにアドレスが入っている(学生のコードから)
mov rdx, greetingLen
syscall
mov rax, 60
mov rdi, 0
syscallこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
基礎のすべてのレッスン
自分で練習してみよう: Assemblyプレイグラウンド