lhu

lhu

RISC-V アセンブリ 参考

lyszt.netはlhuおよびその他のRISC-V命令をより詳しく扱っています。

エンコーディング形式

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

説明

lhu はメモリからハーフワード(16 ビット、つまり 2 バイト)を読み取り、それを符号なしとして扱います。これは lh と対をなし、両者はデスティネーションレジスタの上半分をどのように埋めるかが異なります。どちらも同じアドレッシングで 16 ビットを読み取ります。ハーフワードとアドレッシング形式については lh のページで扱っています。lhu の形式を以下に示します。

lhu rd, offset(rs1)

レジスタは 32 ビットを保持するため、16 ビットのロードでは上位 16 ビットを埋める必要があります。lh は符号ビットをそれらにコピーし、負の数を負のまま保ちます。lhu はそれらを 0 で埋め、これはゼロ拡張と呼ばれ、結果は常に非負で 0 から 65535 の範囲になります。名前の u は符号なし読み取りを表します。

どちらを使うかはデータが決めます。負になり得る値には lh を、決して負にならない値には lhu を選びます。ビットパターン 0xFFFF を lhu でロードすると 65535 になり、同じビットを lh でロードすると -1 になります。

RISC-V マニュアルでは、lhu はメモリから 16 ビット値をロードし、rd に格納する前に 32 ビットにゼロ拡張すると定義されています。実効アドレスはレジスタ rs1 に符号拡張された 12 ビットオフセットを加えたものです。

ほとんどの 16 ビットデータは符号なしです。一部のテキストエンコーディングの文字コード、ネットワークデータのポート番号やチェックサム、16 ビットのピクセル形式、ファイル形式の長さフィールドなどが例です。符号拡張では、最上位ビットがセットされるとそれらのいずれに対しても誤った値になるため、lhu が正しいロードです。ハーフワードは 2 バイト間隔で並ぶため、それらを反復するループではアドレスを 2 ずつ進めます。

例

.data
val: .half 0xffff
.text
la t0, val
lhu t1, 0(t0)   # t1 = 65535 (zero-extended)