Разработка цифровых ИС на примере микроконтроллерного ядра SCR1 - прgграммное обеспечение
Пример использования:
li s1, -0x1000 - загрузка в регистр s1 числа 0xfffffffffffff000 = -4096
srai s1, s1, 2 - результат в s1 будет 0xfffffffffffffc00 = -1024
Примеры
lui s1, 1 -> s1 содержит 0x1000 auipc s2, 1 -> s2 содержит pc + 0x1000
- Load upper immediate: lui rd, imm загружает imm в старшие 20 бит регистра rd, заполняя младшие 12 бит нулями.
- Add upper immediate to pc: auipc rd, imm используется для построения адресов относительно pc (Program Counter - регистр, в котором хранится адрес текущей инструкции). Складывает значение pc и (imm << 12), помещая результат в rd.
Пример использования: Псевдоинструкция la rd, symbol загружает адрес метки symbol в rd и интерпретируется компилятором как:
auipc rd, symbol[31:12] addi rd, rd, symbol[11:0]
Примеры
add gp, s0, s1 -> gp = s0 + s1 and s0, t0, a0 -> s0 = t0 & a0 or s5, s4, s3 -> s5 = s4 | s3 sll a0, a1, a2 -> a0 = a1 << a2 srl s0, s1, s2 -> s0 = s1 >> s2 sub sp, t0, s2 -> sp = t0 - s2
Инструкции, выполняющие арифметические и логические операции, могут оперировать как с непосредственными значениями (описанными ранее), так и со значениями в регистрах.
После названия инструкции (insn) указывается rd - регистр, в который будет записан результат, а также два операнда: rs1 и rs2:
insn rd, rs1, rs2
No operation
Примеры
Исходный код
first_insn: mv a1, s10 .align 4 second_insn: mv s10, a1
Дизассемблированный код
<first_insn>: 0x0: mv a1, s10 0x2: c.nop 0x4: nop 0x8: nop 0xc: nop <second_insn>: 0x10: mv s10,a1
Применяется для выравнивания адресов данных и инструкций в памяти
Инструкция nop не изменяет никаких значений в регистрах или памяти, кроме увеличения pc и инкрементирования имеющихся счетчиков производительности.
Применение:
Существует ассемблерная директива .align <N>, осуществляющая размещение последующей инструкции/данных по адресу выравненному по границе байт.
Безусловные переходы
Примеры
jal s0, label -> s0 = pc + 4, переход по адресу метки label … label: *some code*
- Jump and link: jal rd, label совершает переход по адресу label, и записывает в rd адрес инструкции, следующей за переходом (pc + 4).
- Стандартизированное соглашение о вызовах использует x1 как регистр, содержащий адрес возврата, и x5 как дополнительный регистр, использующийся при необходимости сохранения значения в x1.
- Зачастую при написании ассемблерного кода применяется псевдоинструкция j label, которая интерпретируется как jal x0, label.
Примеры
la s0, label -> загрузка адреса в s0 jalr s0 -> переход по адресу в s0 … label: *some code*
Можно использовать числа в качестве меток и указывать положение относительно инструкции: f - forward, b - backwards
Jump and link register: jal rd, rs1, imm, результирующий адрес образуется сложением значения в регистре rs1 и imm, записывает в rd адрес следующей инструкции (pc + 4).
При написании ассемблерного кода используется псевдоинструкция jalr rs1 <-> jalr ra, rs1, 0, совершающая переход по адресу, хранящемуся в rs1.
! Все инструкции переходов вызывают срабатывание исключения при переходе по адресу, который не выровнен на 4 байта.