Введение

Непрямой переход (также известный как вычисляемый переход, косвенный переход и переход через регистр) — это тип инструкции управления программой, присутствующий в некоторых наборах команд машинного языка. В отличие от прямого перехода, который указывает адрес следующей инструкции для выполнения, аргумент в непрямом переходе указывает, где находится этот адрес. Например, "перейти косвенно через регистр r1" означает, что следующая инструкция для выполнения находится по адресу, содержащемуся в регистре r1. Адрес перехода неизвестен до выполнения инструкции. Непрямые переходы также могут зависеть от значения в ячейке памяти. Непрямой переход может быть полезен для реализации условного перехода, особенно многовариантного. Например, на основе входных данных программы, значение может быть найдено в таблице переходов, содержащей указатели на код для обработки различных случаев, определяемых входным значением. Это значение может быть добавлено к адресу таблицы, а результат сохранен в регистре. Затем можно выполнить косвенный переход на основе значения этого регистра, эффективно перенаправляя управление программой в соответствующий код. Аналогично, инструкции вызова подпрограммы могут быть непрямыми, при этом адрес вызываемой подпрограммы хранится в памяти. Указатели на функции обычно реализуются с помощью непрямых вызовов подпрограмм. Непрямые переходы были одной из векторов атаки в уязвимости Spectre. Для снижения риска атаки GCC 8.1 представил следующие новые опции: mindirect branch=, mfunction return= и mindirect branch register.