Для чего используется ключевое слово fastcall в visual c?

Я видел fastcall нотация добавлена перед многими функциями. Почему он используется?

2 ответов


что записи, функция называется "конвенция."Он указывает, как (на низком уровне) компилятор передаст входные параметры функции и получит ее результаты после ее выполнения.

существует множество различных соглашений о вызовах, самым популярным из которых является stdcall и cdecl.

вы можете подумать, что есть только один способ сделать это, но на самом деле есть десятки способов вызвать функцию и передать переменные и из. Вы можете поместить входные параметры в стек (push, push, push to call; pop, pop, pop для чтения входных параметров). Или, возможно, вы предпочли бы вставить их в регистры (это fastcall - он пытается соответствовать некоторым входным парам в регистрах для скорости).

но тогда как насчет заказа? Вы толкаете их слева направо или справа налево? Как насчет результата-всегда есть только один (при условии отсутствия ссылочных параметров), поэтому вы помещаете результат в стек, в зарегистрироваться по определенному адресу памяти?

кроме того, предположим, что вы используете стек для связи - чья задача на самом деле очистить стек после вызова функции - вызывающий или вызываемый?

как насчет резервного копирования, а затем восстановления содержимого (определенных) регистров CPU - должен ли вызывающий это сделать, или вызываемый гарантирует, что он вернет все так, как было?

самое популярное вызывающее соглашение (на сегодняшний день) cdecl, что является стандартным соглашением о вызовах как на C, так и на C++. WIN32 API использует stdcall, Что означает, что любой код, вызывающий WIN32 API, должен использовать stdcall для этих вызовов функций (что делает его еще одним популярным выбором).

fastcall немного странный-люди, реализованные для многих функций только с одним параметром in/ out, толкая и выскакивая из стека на основе памяти, довольно много накладных расходов и делает вызовы функций немного тяжелыми, поэтому разные компиляторы введены (разные) соглашения о вызовах, которые помещают один или несколько параметров в регистры перед размещением остальных в стеке для повышения производительности. Проблема в том, что не все компиляторы использовали одни и те же правила для того, что куда идет и кто что делает с fastcall, и в результате вы должны быть осторожны при его использовании, потому что вы никогда не узнаете, кто что делает. Наконец, смотрите действительно ли fastcall быстрее? подробнее о fastcall выигрыш в производительности.

сложные материал.

что-то важное, чтобы иметь в виду: не добавлять или изменять соглашения о вызовах, если вы не знаете ровно что вы делаете, потому что, если и вызывающий абонент и вызываемый абонент не согласны с соглашением о вызове, вы, вероятно, в конечном итоге с коррупцией стека и segfault. Это обычно происходит, когда у вас есть функция, вызываемая в DLL / общей библиотеке, и пишется программа, которая зависит от DLL / SO/dylib, являющегося определенным соглашением о вызове (скажем, cdecl), затем библиотека перекомпилируется с другим соглашением о вызовах (скажем, fastcall). Теперь старая программа больше не может общаться с новой библиотекой.


Википедия утверждает, что

соглашения под названием fastcall не были стандартизированы и были реализованы по-разному, в зависимости от поставщика компилятора. Обычно соглашения о вызовах fastcall передают один или несколько аргументов в регистрах, что уменьшает количество обращений к памяти, необходимых для вызова.