Предположим, у нас есть функция C (или C++) со следующей сигнатурой:
void foo(int64_t a, double b, int64_t c, double d);
При компиляции в Linux, Mac или любой ОС, использующей System V ABI (x86_64), a
и c
передаются в регистрах rdi
и rsi
, а b
и d
передаются в xmm0
и xmm1
. Хорошо, в этом нет ничего плохого. Но потом я делаю то же самое в Windows (x86_64), и похоже, что он пропускает некоторые регистры. a
и c
передаются в rcx
и r8
(rdx
пропускаются), а b
и d
передаются в xmm1
и xmm3
(xmm0
и xmm2
пропускаются). Почему Win64 делает это вместо того, чтобы «сжимать» аргументы, как System V? Я предполагаю, что с System V можно передать, скажем, 4 qword и 4 double без необходимости передавать что-либо в стек, тогда как Win64, как я предполагаю, будет передавать все, что находится после 4-го аргумента в стеке.
Я знаю о различиях в порядке регистров при передаче аргументов в Win64 и SysV, но порядок не должен иметь значения. Мне просто любопытно, почему Win64 пропускает регистры, особенно когда у него всего 4 для передачи аргументов без стека.
__fastcall
, и простой в реализации вариативный функции, а не новый дизайн для высокой производительности с обычными (невариативными) функциями. (Работаю над ответом на этот вопрос, опубликую позже). - person Peter Cordes   schedule 19.08.2017