sub

sub

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

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

Описание

sub вычитает значение одного регистра из другого и записывает результат в третий. Оно работает с регистрами — небольшими пронумерованными ячейками памяти внутри процессора, каждая из которых содержит одно 32-битное число.

Форма вызова sub показана ниже, а результат равен rd = rs1 - rs2. rd — это регистр назначения, в который записывается результат. rs1 и rs2 — это исходные регистры. Порядок имеет значение, и его перестановка — распространённая ошибка новичков.

sub rd, rs1, rs2

В следующей строке вычисляется t0 минус t1. Левый источник — это значение, из которого производится вычитание.

sub t2, t0, t1

Инструкции subi для вычитания константы не существует. Инструкция addi поддерживает отрицательные константы, поэтому вычитание фиксированного числа означает сложение его отрицательного значения. В следующей строке значение t0 уменьшается на единицу.

addi t0, t0, -1

В RISC-V есть специальный регистр с именем zero, который всегда содержит значение 0. Вычитание числа из zero меняет его знак, поэтому в следующей строке в t0 помещается отрицательное значение t1. Инструкция neg является сокращённым написанием этого.

sub t0, zero, t1

В руководстве по RISC-V команда sub определяется как вычитание rs2 из rs1. Переполнение игнорируется, и в регистр rd записываются только младшие биты XLEN результата, где XLEN — ширина регистра в битах, которая в данном случае равна 32. В руководстве также указано, что регистр x0, который в данном симуляторе называется zero, жестко задан значением, все биты которого равны 0.

В примере 10 минус 4 даёт 6 в t2. Перестановка двух операндов даёт -6, которое процессор сохраняет в соответствии со своей собственной схемой представления отрицательных чисел.

Пример

li t0, 10
li t1, 4
sub t2, t0, t1   # t2 = 6