В компьютерном программировании слово « батут» имеет несколько значений и обычно ассоциируется с прыжками (т. Е. Переходом на разные пути кода).
Низкоуровневое программирование
Батуты (иногда называемые векторами непрямого перехода ) - это ячейки памяти, содержащие адреса, указывающие на процедуры обслуживания прерываний, процедуры ввода-вывода и т. Д. Выполнение переходит в трамплин, а затем немедленно выпрыгивает или отскакивает, отсюда и термин батут . У них много применений:
- Батут может использоваться для преодоления ограничений, накладываемых архитектурой центрального процессора (ЦП), которая всегда ожидает найти векторы в фиксированных местах.
- Когда операционная система загружается на машине с симметричной многопроцессорной обработкой (SMP), будет активен только один процессор, процессор начальной загрузки. После того, как операционная система настроена, она проинструктирует другие процессоры перейти к фрагменту кода-трамплина, который инициализирует процессоры и будет ждать, пока операционная система начнет планировать потоки для них.
Программирование высокого уровня
- Как используется в некоторой Lisp реализациях, батут есть цикл , который итеративно вызывает санк -returning функции ( продолжение обхода стиля ). Одного батута достаточно, чтобы выразить все передачи управления программой; программа, выраженная таким образом, является батутной или в стиле батута ; преобразование программы в стиль прыжков на батуте - это прыжок на батуте. Программисты могут использовать замещающие функции для реализации хвостовых рекурсивных вызовов функций в стек-ориентированных языках программирования . [1]
Стиль передачи с продолжением - популярный промежуточный формат для компиляторов функциональных языков, потому что многие конструкции потока управления могут быть элегантно выражены, а оптимизация хвостового вызова проста. При компиляции на язык без оптимизированных хвостовых вызовов можно избежать роста стека с помощью техники, называемой trampolining. Идея состоит в том, чтобы не сделать последний вызов продолжения внутри функции, а выйти и вернуть продолжение в трамплин. Этот батут - это просто цикл, который вызывает возвращенные продолжения. Следовательно, нет вложенных вызовов функций и стек не будет расти. [2]
- В Java , батут относится к использованию отражения , чтобы избежать использования внутренних классов , например , в слушателях событий. Накладные расходы времени на вызов отражения заменяются накладными расходами пространства внутреннего класса. Батуты в Java обычно включают создание GenericListener для передачи событий внешнему классу. [3]
- При взаимодействии частей кода с несовместимыми соглашениями о вызовах используется трамплин для преобразования соглашения вызывающего в соглашение вызываемого.
- Во встроенных системах батуты - это короткие фрагменты кода, запускающие другие фрагменты кода. Например, вместо того, чтобы писать обработчики прерываний полностью на языке ассемблера, другой вариант - написать обработчики прерываний в основном на языке C и использовать короткий трамплин для преобразования соглашения о вызовах прерываний на языке ассемблера в соглашение о вызовах C. [4]
- При передаче обратного вызова системе, которая ожидает вызова функции C , но кто-то хочет, чтобы она выполняла метод конкретного экземпляра класса, написанного на C ++ , используется короткий трамплин для преобразования соглашения о вызове функций C в C ++. соглашение о вызове методов. Один из способов написать такой батут - использовать преобразователь . [5] Другой метод - использовать общий слушатель . [3]
- В Objective-C батут - это объект, возвращаемый методом, который захватывает и перерабатывает все сообщения, отправленные ему, а затем «пересылает» эти сообщения другому объекту, например, при обмене сообщениями более высокого порядка . [6]
- В компиляторе GCC трамплин означает метод реализации указателей на вложенные функции . [7] Батут - это небольшой фрагмент кода, который создается на лету в стеке, когда берется адрес вложенной функции. Батут устанавливает статический указатель ссылки, который позволяет вложенной функции получать доступ к локальным переменным включающей функции. Тогда указатель на функцию - это просто адрес батута. Это позволяет избежать использования «жирных» указателей на вложенные функции, которые несут как кодовый адрес, так и статическую ссылку. [8] [9] [10] Однако это противоречит тенденции сделать стек неисполняемым, хотя и по соображениям безопасности.
- В эзотерическом языке программирования Befunge батут - это инструкция пропустить следующую ячейку в потоке управления .
Неисполняемые стеки
Некоторые реализации трамплинов вызывают потерю стека невыполнения (стек NX). В частности, в коллекции компиляторов GNU (GCC) вложенная функция строит трамплин в стеке во время выполнения, а затем вызывает вложенную функцию через данные в стеке. Батут требует, чтобы стек был исполняемым.
В GCC стеки без выполнения и вложенные функции являются взаимоисключающими. Если вложенная функция используется при разработке программы, стек NX автоматически теряется. GCC предлагает предупреждение -Wtrampolines для предупреждения о состоянии.
Программное обеспечение, спроектированное с использованием безопасного жизненного цикла разработки, часто не позволяет использовать вложенные функции из-за потери стеков NX. [11]
Смотрите также
- DLL батут
- Retpoline
Рекомендации
- ↑ Бейкер, Генри Г. (сентябрь 1995 г.). «Минусы не должны ПРОТИВ его аргументов, Часть II: Чейни на MTA» Уведомления ACM SIGPLAN . 30 (9): 17–20. DOI : 10.1145 / 214448.214454 . Архивировано из оригинала на 2016-11-11.
- ^ Асинхронное программирование и стиль передачи продолжения в JavaScript - 2ality
- ^ а б Мюллер, Ганс (31 января 2005 г.). «Утверждение контроля над графическим интерфейсом пользователя: команды, значения по умолчанию и пакеты ресурсов» . today.java.net . Батуты . Проверено 6 ноября 2015 . [1]
- ^ Линк, Джозеф М. (01.09.2001). «Батуты для встроенных систем: минимизация задержки обработчиков прерываний» . Журнал доктора Добба . Архивировано 27 мая 2018 года . Проверено 26 мая 2018 .
- ^ Стангвик, Эйнар Отто (16 августа 2006 г.). «Преобразование Win32 с C ++» . Архивировано из оригинала на 2012-10-15.
- ^ Вейхер, Марсель (2004). «Обмен сообщениями высшего порядка (HOM)» (PDF) . Архивировано (PDF) из оригинала 27.05.2018 . Проверено 26 мая 2018 .
- ^ fuz (18.11.2011). «Реализация вложенных функций» . StackOverflow . Архивировано 29 марта 2016 года . Проверено 26 мая 2018 .
- ^ «Батуты для вложенных функций» . Использование коллекции компиляторов GNU (GCC) . 2018 [2002]. 18.11. Архивировано 27 мая 2018 года . Проверено 26 мая 2018 .
- ^ «Вложенные функции» . Использование коллекции компиляторов GNU (GCC) . 2018 [2002]. 6.4. Архивировано 27 мая 2018 года . Проверено 26 мая 2018 .
- ^ Бруэль, Томас М. (2013). «Лексические замыкания для C ++» (PDF) . Архивировано (PDF) из оригинала 12.12.2017 . Проверено 26 мая 2018 .
- ^ Уолтон, Джеффри; Манико, Джим; Уолл, Кевин (2018-03-02) [2013]. «Укрепление инструментальной цепочки на основе C» . Открытый проект безопасности веб-приложений (OWASP). Архивировано 27 мая 2018 года . Проверено 2 марта 2018 .