入出力

入出力

はすべての入出力を処理します。(environment call)は、オペレーティングシステムまたはシミュレータに対して、あなたのアセンブリコードのためにサービスを実行するよう要求します。画面とキーボードは、この方法で利用できるサービスのうちの2つです。

サービス番号 を a7 に、任意の 引数 を a0 に設定し、 をトリガーします。このシミュレータが認識するサービスは次のとおりです:

サービス (a7)
1 # 整数を出力 (a0 = 数値)
4 # 文字列を出力 (a0 = テキストのアドレス)
5 # 整数を読み取る (結果はa0に返る)
10 # プログラムを終了
32 # 一時停止 (a0 = ミリ秒)
サービスコール
program
a71
a0値
ecall
system数値を出力します

a7 = 1 は印刷サービスを選択します。

すべてのサービスは、同じ 2 レジスタのハンドシェイクを共有しています。a7 は実行するサービスを指定し、a0 にはそのサービスが必要とするもの(出力する値、読み込むアドレス、待機時間など)が格納されます。 このリストは5項目と短く固定されているため、このハンドシェイクを一度覚えれば、このシミュレータが外部と通信するあらゆる方法を網羅できます。実際のオペレーティングシステムでは、同じ考え方を用いて、はるかに長いリストへと拡張しています。
数値を読み込み、2倍にして、出力する
li a7, 5 # 整数を読み取る -> a0
ecall
add a0, a0, a0 # 2倍にする
li a7, 1 # 整数を出力
ecall
li a7, 10
ecall

は整数の読み取りを選択し、 は入力を待って、あなたの数値を a0 に返します。 は a0 を自身に加算し、その場で2倍にします。次に と が結果を出力し、 と が終了します。Run すると、シミュレータが入力ボックスをポップアップ表示します。数値を入力すると、2倍になって返ってくるのを確認できます。

テキストの出力

まず、2つの新しい用語について説明します。セクションとは、プログラム内のラベル付けされた領域のことです。命令は .text セクションに格納され、テキストのような固定データは .data セクションに格納されます。 また、アドレスとは、メモリ内の1つのスロットを特定する単なる数値のことです。文字列全体を保持する代わりに、レジスタにはその文字列の先頭アドレスを格納しておき、printサービスがその場所から読み込むことができます。

テキストはデータセクションに入ります。それにラベルを付け、("load address")を使ってそのラベルのアドレスをロードし、サービス4で出力します。

こんにちは、RISC-V
.data
msg: .string "Hello, RISC-V!\n"
.text
la a0, msg # a0 = テキストのアドレス
li a7, 4 # 文字列を出力
ecall
li a7, 10
ecall

.dataでは、ディレクティブがテキスト用のスペースを確保し、ラベルmsgを付けます。.stringは文字を格納し、\n(改行)を追加します。.textでは、がテキストのアドレスをa0に入れ、が文字列出力サービスを選択し、がそのアドレスから文字列の終端に達するまで文字を出力します。その後、プログラムは通常どおり終了します。