Comments 12
Интересная статья, однако стоило бы указать, к какой именно архитектуре относятся данные соглашения.
Например, везде в коде однозначно используется x86, однако в vectorcall затрагиваются регистры x64, хотя, безусловно, данное соглашение существует и для x86, и для x64 (https://docs.microsoft.com/ru-ru/cpp/cpp/vectorcall?view=msvc-170):
(RCX/XMM0, RDX/XMM1, R8/XMM2, R9/XMM3 + XMM0-XMM5/YMM0-YMM5)
Хотелось бы увидеть чуть более подробное описание vectorcall.
Также стоило бы упомянуть, что вы используете Win32 ABI, т.к. в System V ABI есть отличия для наименований, количестве передаваемых в регистрах аргументов для fastcall и т.д.
Но ссылкку приложить - не, да зачем?
Как видите, Хабр её потерял: https://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions
Можно заметить, что при всей несимметричности stdcall (белье в стиралку загружает один эктор, а выплевывает после стирки она сама столько, сколько разумеет), ret <n> - самая эффективная команда выбрасывания отработанного стекового кадра, которая при этом ещё и не портит флаги.
Возможно кому-то будет полезно, как легко не путать stdcall и cdecl: cdecl начинается с "C", названия языка программирования, в котором есть printf, известная функция с переменным числом аргументов, которое известно только снаружи функции. Соответственно и очищается стек снаружи.
И как же printf выполняет свою задачу не зная даже сколько аргументов ей передали?
В мире существует всего два способа для этого: передать кол-во заранее в условленном месте, и «копать, пока лопата не стукнется о сундук» - для printf используются оба - первый для передачи количества аргументов, второй - для вывода количества символов в каждой выводимой строке )
Сколько минимум тактов процессора необходимо для вызова С-функции?
Соглашения о вызовах