Menu
Coddy logo textTech

Buffer Address (rsi)

CoddyのAssemblyジャーニー「基礎」セクションの一部。レッスン 37/45。

write syscallでは、出力の送信先(rdi内のファイルディスクリプタ)をOSに伝えた後、何を出力するかを伝える必要があります。これは、メモリ内の文字列のaddressを渡すことで行います。

バッファのアドレス用のレジスタはrsiです。

バッファとは何ですか?

バッファとは、データを保持するメモリの単純なブロックです。今回の場合、バッファは印刷したい文字列です。

なぜ値そのものではなく、address なのか?

write syscall は、メモリ内で string がどこから始まるかを知る必要があります。write syscall は、その address から、rdx で指定した長さに達するまで bytes を読み取ります。実際の文字を write syscall に送るのではありません。それらの場所を送ります。

例:

section .data
    msg db 'Hello', 0x0a

section .text
    mov rsi, msg        ; rsi は msg のアドレスを保持します

msg の正体:

msg はラベルです。アセンブラはこれを数値、つまり 'Hello' という string が格納されているメモリのアドレスに置き換えます。mov rsi, msg と記述すると、そのアドレスの数値を rsi に入れることになります。

アドレスを忘れるとどうなりますか?

rsiを設定しない場合、レジスタには以前そこにあった無関係な値が入っています。OSはランダムなメモリアドレスから読み取ろうとするため、セグメンテーションフォールト(クラッシュ)が発生する可能性が高くなります。

write syscall を使った完全な例:

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 に読み込むコード行を書いてください。

rsimov 命令だけを書いてください。

自分で試してみよう

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プレイグラウンド