lw
lyszt.net охватывает lw и другие инструкции RISC-V более подробно.
Формат кодирования
Описание
lw копирует значение из памяти в регистр. 32 регистра образуют небольшую быструю рабочую область процессора. Память располагается рядом с ними как большое хранилище: длинный ряд пронумерованных ячеек, который содержит массивы, текст и переменные. Номер ячейки — это её адрес. Вычисления происходят в регистрах, а данные ожидают в памяти между использованиями.
RISC-V выполняет арифметику только над регистрами, никогда напрямую над памятью, поэтому значение должно быть загружено в регистр перед использованием и сохранено обратно после. lw выполняет загрузку. Название означает load word (загрузить слово), а слово — это 32-битное значение, ширина одного регистра.
Форма lw показана ниже. Она берёт значение из rs1, регистра, содержащего адрес памяти, называемый базой, добавляет offset, небольшую константу, и читает значение по полученному адресу в регистр назначения rd.
lw rd, offset(rs1)
Следующая строка загружает значение на 8 байт дальше адреса в t0.
lw t1, 8(t0)
Руководство RISC-V называет RISC-V архитектурой load-store: инструкции загрузки и сохранения — единственные, которые обращаются к памяти, а арифметические инструкции работают только с регистрами. Адресное пространство составляет 32 бита и адресуется побайтово, а эффективный адрес загрузки — это регистр rs1 плюс 12-битный offset со знаковым расширением. Среда выполнения, то есть система, в которой работает программа, решает, хранит ли память младший значащий байт первым, что называется little-endian, или старший значащий байт первым, что называется big-endian. Доступ является естественно выровненным, когда его адрес делится нацело на размер доступа, который для слова составляет 4 байта. Естественно выровненные доступы никогда не вызывают ошибку выравнивания. Невыровненный доступ ведёт себя так, как определено средой, и может работать очень медленно.
Offset здесь потому, что элементы в памяти располагаются на регулярных расстояниях. Слово — это 4 байта, поэтому последовательные элементы массива лежат на расстоянии 4 байта друг от друга, по смещениям 0, 4, 8 и так далее. la помещает начальный адрес массива в регистр, а изменение offset читает разные элементы. Пример загружает двух соседей массива. Offset 0 даёт первое значение, 10, а offset 4 даёт следующее значение, 20.
Пример
.data arr: .word 10, 20 .text la t0, arr lw t1, 0(t0) # t1 = 10 lw t2, 4(t0) # t2 = 20
