Методика программирования с использованием косвенных переходов
В компьютерном программировании слово « батут» имеет ряд значений и обычно ассоциируется с инструкциями по прыжкам (т. е. переходом к различным ветвям кода).
Низкоуровневое программирование
Трамплины (иногда называемые косвенными векторами перехода) — это ячейки памяти, содержащие адреса, указывающие на процедуры обслуживания прерываний , процедуры ввода-вывода и т. д. Выполнение прыгает на трамплин, а затем немедленно выпрыгивает или отскакивает, отсюда и термин «батут» . Они имеют множество применений:
- Батут можно использовать для преодоления ограничений, накладываемых архитектурой центрального процессора (ЦП), которая всегда предполагает нахождение векторов в фиксированных местах.
- Когда операционная система загружается на симметричной многопроцессорной машине (SMP), активным будет только один процессор, загрузочный процессор. После того, как операционная система настроится, она даст указание другим процессорам перейти к фрагменту кода трамплина, который инициализирует процессоры и будет ждать, пока операционная система начнет планировать потоки на них.
Высокоуровневое программирование
- В некоторых реализациях Lisp трамплин — это цикл, который итеративно вызывает функции возврата thunk ( стиль продолжения-передачи ). Одного трамплина достаточно, чтобы выразить все передачи управления программы; программа, выраженная таким образом, трамплином или в трамплином стиле ; преобразование программы в трамплиный стиль — трамплином. Программисты могут использовать трамплиные функции для реализации вызовов функций с хвостовой рекурсией в языках программирования, ориентированных на стек . [1]
- В Java батут относится к использованию рефлексии для избежания использования внутренних классов , например, в прослушивателях событий. Временные затраты на вызов рефлексии обмениваются на пространственные затраты внутреннего класса. Трамплины в Java обычно подразумевают создание GenericListener для передачи событий внешнему классу. [2]
- В Mono Runtime батуты — это небольшие, написанные вручную фрагменты ассемблерного кода, используемые для выполнения различных задач. [3]
- При сопряжении фрагментов кода с несовместимыми соглашениями о вызовах используется батут для преобразования соглашения вызывающего объекта в соглашение вызываемого объекта.
- В встроенных системах трамплины — это короткие фрагменты кода, которые запускают другие фрагменты кода. Например, вместо того, чтобы писать обработчики прерываний полностью на языке ассемблера, другой вариант — писать обработчики прерываний в основном на языке C и использовать короткий трамплины для преобразования соглашения о вызове прерываний языка ассемблера в соглашение о вызове языка C. [4]
- При передаче обратного вызова в систему, которая ожидает вызова функции C , но хочет, чтобы она выполнила метод конкретного экземпляра класса, написанного на C++ , используется короткий трамплин для преобразования соглашения о вызове функций C в соглашение о вызове методов C++. Один из способов написания такого трамплина — использовать thunk . [ 5] Другой способ — использовать generic listener . [2]
- В Objective-C батут — это объект, возвращаемый методом, который захватывает и материализует все отправленные ему сообщения, а затем «перенаправляет» эти сообщения другому объекту, например, в сообщениях более высокого порядка . [6]
- В компиляторе GCC батут относится к технике реализации указателей на вложенные функции , когда опция включена. [7] Батут — это небольшой фрагмент кода, который конструируется «на лету» в стеке, когда берется адрес вложенной функции. Батут устанавливает статический указатель ссылки, который позволяет вложенной функции получать доступ к локальным переменным включающей функции. Указатель функции затем является просто адресом батута. Это позволяет избежать необходимости использовать «толстые» указатели функций для вложенных функций, которые несут как адрес кода, так и статическую ссылку. [8] [9] [10] Однако это противоречит желанию сделать стек неисполняемым по соображениям безопасности.
-ftrampolines
- В эзотерическом языке программирования Befunge батут — это инструкция пропустить следующую ячейку в потоке управления .
Неисполняемые стеки
Некоторые реализации трамплинов приводят к потере стеков без выполнения (стек NX). В частности, в GNU Compiler Collection (GCC) вложенная функция создает трамплин в стеке во время выполнения, а затем вызывает вложенную функцию через данные в стеке. Для трамплина требуется, чтобы стек был исполняемым.
Неисполняемые стеки и вложенные функции являются взаимоисключающими в GCC. Если вложенная функция используется при разработке программы, то стек NX молча теряется. GCC предлагает предупреждение, -Wtrampolines
чтобы предупредить об этом состоянии.
Программное обеспечение, разработанное с использованием безопасного жизненного цикла разработки, часто не позволяет использовать вложенные функции из-за потери стеков NX. [11]
Смотрите также
Ссылки
- ↑ Бейкер, Генри Г. (сентябрь 1995 г.). «CONS Should Not CONS Its Arguments, Part II: Cheney on the MTA» ACM SIGPLAN Notices . 30 (9): 17–20. doi :10.1145/214448.214454. S2CID 20720831. Архивировано из оригинала 11.11.2016.
- ^ ab Muller, Hans (2005-01-31). "Утверждение контроля над графическим интерфейсом: команды, значения по умолчанию и пакеты ресурсов". today.java.net . Батуты . Получено 2015-11-06 .[1]
- ^ "Батуты". Mono Project. 8 октября 2022 г.
- ^ Линк, Джозеф М. (2001-09-01). "Трампулы для встраиваемых систем: минимизация задержки обработчиков прерываний". Журнал доктора Добба . Архивировано из оригинала 27-05-2018 . Получено 26-05-2018 .
- ^ Stangvik, Einar Otto (2006-08-16). "Thunking in Win32 with C++". Архивировано из оригинала 2012-10-15.
- ^ Weiher, Marcel (2004). "Higher Order Messaging (HOM)" (PDF) . Архивировано (PDF) из оригинала 2018-05-27 . Получено 2018-05-26 .
- ^ fuz (2011-11-18). "Реализация вложенных функций". StackOverflow . Архивировано из оригинала 2016-03-29 . Получено 2018-05-26 .
- ^ "Trampolines for Nested Functions". Использование коллекции компиляторов GNU (GCC) . 2018 [2002]. 18.11. Архивировано из оригинала 2018-05-27 . Получено 2018-05-26 .
- ^ "Вложенные функции". Использование коллекции компиляторов GNU (GCC) . 2018 [2002]. 6.4. Архивировано из оригинала 2018-05-27 . Получено 2018-05-26 .
- ^ Брейел, Томас М. (2013). "Лексические замыкания для C++" (PDF) . Архивировано (PDF) из оригинала 2017-12-12 . Получено 2018-05-26 .
- ^ Уолтон, Джеффри; Манико, Джим; Уолл, Кевин (2018-03-02) [2013]. "Усиление безопасности цепочки инструментов на основе C". Открытый проект безопасности веб-приложений (OWASP). Архивировано из оригинала 2018-05-27 . Получено 2018-03-02 .