addi

addi

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

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

Описание

addi добавляет константу к регистру. Название означает add immediate (сложить с непосредственным значением). Непосредственное значение — это константа, записанная в самой инструкции, а не считанная из регистра. Используйте её, когда одно из чисел фиксировано при написании программы, например при добавлении 1 к счётчику.

Форма addi показана ниже. Она читает значение из исходного регистра rs1, добавляет константу imm и записывает результат в регистр назначения rd.

addi rd, rs1, imm

Следующая строка читает t0, добавляет единицу и записывает результат обратно, так что t0 = t0 + 1.

addi t0, t0, 1

Константа занимает 12 бит и является знаковой, что даёт диапазон от -2048 до 2047. Ассемблер отвергает большие значения. Для большей константы сначала загрузите её в регистр с помощью li. Отрицательная константа заставляет addi также вычитать, поэтому в RISC-V нет отдельной инструкции вычитания непосредственного значения. Следующая строка ведёт отсчёт вниз.

addi t0, t0, -1

Руководство RISC-V называет константу 12-битным непосредственным значением с расширением знака. В нём указано, что арифметическое переполнение игнорируется, поэтому результат сохраняет только свои младшие XLEN бит, где XLEN — ширина регистра в битах, здесь 32. Когда знак константы известен, одна ветвь после сложения проверяет знаковое переполнение. Две строки ниже обрабатывают распространённый случай добавления положительной константы.

addi t0, t1, +imm
blt t0, t1, overflow

Программы используют addi для счётчиков, для перемещения указателя к следующему элементу и для резервирования места в стеке. Пример добавляет 1, чтобы продвинуть счётчик, и добавляет -16, чтобы зарезервировать 16 байт рабочей памяти, — так обычно начинается функция, которой нужно рабочее пространство.

Пример

addi t0, t0, 1     # t0++
addi sp, sp, -16   # reserve 16 bytes of stack