auipc

auipc

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

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

Описание

auipc расшифровывается как add upper immediate to PC. Она работает как lui, принимая 20-битную константу в качестве старшей части значения. auipc добавляет это значение к счётчику команд, который хранит адрес текущей выполняемой инструкции (см. страницу beq). Результатом является адрес, измеряемый относительно того места, где эта инструкция находится в памяти.

Относительные адреса решают реальную проблему. Программа не всегда знает, куда в памяти она будет загружена. Код, который обращается к своим данным по фиксированным абсолютным адресам, даёт сбой, когда его загружают в другое место. Код, который вычисляет адреса относительно текущей инструкции, работает везде, куда бы его ни поместили. Это свойство называется позиционной независимостью.

auipc предоставляет грубую часть такого адреса, а следующая инструкция добавляет точный 12-битный остаток. Инструкция la, которая загружает адрес метки, построена из этой пары, как и вызовы удалённых функций.

Руководство RISC-V говорит, что текущий pc можно получить, установив константу auipc в 0. auipc, за которым следует jalr, может передать управление на любой 32-битный адрес относительно pc, а auipc, за которым следует загрузка или сохранение с 12-битным смещением, может получить доступ к любому 32-битному адресу данных относительно pc.

la и call существуют, чтобы вам не приходилось писать auipc вручную, и она часто появляется в трассировке симулятора и в дизассемблированном коде. auipc, за которым следует инструкция с небольшим смещением, вместе образующие один адрес, — это полезный шаблон, который стоит распознавать.

Пример

auipc t0, 1      # t0 = pc + 0x1000