sh

sh

RISC-V Ассемблер Ссылка

lyszt.net охватывает sh и другие инструкции 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

Описание

sh записывает полуслово, 16 бит или 2 байта, в память. Он соответствует загрузкам lh и lhu и сохраняет более узкий размер там, где sw сохраняет полное слово. Форма показана ниже. Он берёт значение из регистра-источника rs2 и записывает его младшие 16 бит по адресу в базовом регистре rs1 плюс смещение. Раскладка соответствует sw, с регистром-источником, указанным первым.

sh rs2, offset(rs1)

Регистр содержит 32 бита, а сохраняются только 16, поэтому sh сохраняет младшие 16 и отбрасывает старшие 16. У записей нет выбора между знаковым и беззнаковым. Этот выбор принадлежит загрузкам, где узкое значение должно быть расширено для заполнения регистра, и для недостающих битов нужно правило. Запись сужает значение, и сохранение младших битов — единственное поведение, которое имеет смысл. Если регистр содержит значение, слишком большое для 16 бит, лишние биты теряются без предупреждения, поэтому проверяйте диапазон перед записью.

Руководство RISC-V говорит, что sh сохраняет младшие 16 бит регистра rs2 в память по адресу rs1 плюс 12-битное смещение со знаком. Записи полуслова по чётным адресам естественно выровнены и никогда не вызывают ошибку выравнивания. Запись по адресу, который не выровнен естественно, ведёт себя так, как определено средой выполнения, и руководство говорит, что она может выполняться крайне медленно.

sh записывает любой 16-битный формат, который lh и lhu читают обратно, например аудиосэмплы, 16-битные данные пикселей и массивы полуслов. Распространённый шаблон — чтение, изменение и запись. Загрузите полуслово с помощью lhu, измените его в регистре и сохраните обратно с помощью sh. Изменяются только целевые 2 байта, а байты вокруг них остаются как были. Полуслова расположены на расстоянии 2 байта друг от друга, поэтому циклы сдвигают адрес на 2.

Пример

la t0, slot
li t1, -5
sh t1, 0(t0)   # memory at slot now holds the low 16 bits of -5