mret
lyszt.net охватывает mret и другие инструкции RISC-V более подробно.
Описание
mret выполняет возврат из обработчика ловушки. Ловушка возникает, когда процессор останавливает выполняемую программу, чтобы обработчик мог взять управление на себя. Обработчик — это подпрограмма по фиксированному адресу. Устройство вызывает прерывание, например кнопка на плате GPIO, и это запускает ловушку. Название означает возврат в машинном режиме.
mret
Когда начинается ловушка, процессор сохраняет адрес прерванной инструкции в mepc, записывает причину в mcause, сбрасывает глобальный бит разрешения прерываний в mstatus и переходит по адресу обработчика, хранящемуся в mtvec. mret отменяет это. Он загружает счётчик команд адресом из mepc и восстанавливает бит разрешения прерываний, который mstatus сохранил в начале ловушки. Прерванная программа затем возобновляется с инструкции, которую собиралась выполнить.
mret не принимает операндов. Без него процессор продолжает за концом обработчика в код, который следует далее.
Прерывание может прийти между любыми двумя инструкциями, и прерванная программа не подготовилась к нему. Поэтому обработчик сохраняет каждый регистр, который изменяет, и восстанавливает их перед mret.
Обработчик кнопки также сбрасывает бит ожидания кнопки перед mret. Если этот бит останется установленным, то же прерывание сработает снова, как только mret снова включит прерывания.
Пример записывает адрес target в mepc и выполняет mret, который переходит туда. Вне настоящей ловушки это показывает сам переход. См. csrw для записи CSR.
Пример
la t0, target csrw mepc, t0 mret # pc = mepc, so execution continues at target target: nop
