auipc
lyszt.net охватывает auipc и другие инструкции RISC-V более подробно.
Формат кодирования
Описание
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
