Menu
CoddyTech

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
challenge icon

チャレンジ

改行が続く値 '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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

基礎のすべてのレッスン

自分で練習してみよう: Assemblyプレイグラウンド