Передача параметров
Первые 4 аргумента целого числа передаются в регистрах.Целочисленные значения передаются в порядке (слева направо) в RCX, RDX, R8 и R9.Чем выше передаются аргументы 5 и в стек.Все аргументы временной вправо в регистрах.Это делается для того, чтобы вызываемый мог игнорировать старшие разряды регистра при необходимости и получить доступ только к необходимой части регистра.
Аргументы значений с плавающей запятой и двойной точностью передаются в XMM0 – XMM3 (до 4) с помощью гнезда целых чисел (RCX, RDX, R8 и R9), которое обычно и используется, в то время как гнездо кардинальных чисел отклоняется (см. пример) и наоборот.
типы, массивы и строки __m128 никогда не передаются непосредственно, а указатель передается в выделенной памяти вызывающим объектом.Передаются структуры или объединения размера в 8, 16, 32 или 64 - и __m64, если она была целыми числами того же размера.Структуры или объединения, отличный от этих размеров передаются как указатель на выделенную память вызывающим объектом.Для этих агрегатных типов, передаваемых в качестве указателя (включая __m128), память должна быть выровнена по 16 разряду.
Встроенные функции, которые не выделяют пространства в стеке и не вызывают других функций, могут использовать иные изменяемые регистры для передачи дополнительных аргументов в регистры, так как существует тесная связь между компилятором и реализацией встроенной функции.Это дополнительная возможность увеличения производительности.
Вызываемый несет ответственность за сбрасывание при необходимости параметров регистра в теневое пространство.
В следующей таблице подведены итоги передачи параметров:
Тип параметра |
Передача |
---|---|
С плавающей запятой |
Первые 4 параметра — от XMM0 к XMM3.Остальные передаются в стек. |
Integer |
Первые 4 параметра — RCX, RDX, R8, R9.Остальные передаются в стек. |
Агрегатные параметры (8, 16, 32 или 64-разрядные) и __m64 |
Первые 4 параметра — RCX, RDX, R8, R9.Остальные передаются в стек. |
Агрегатные параметры (другие) |
Указатель.Первые 4 параметра, переданные в качестве указателей в RCX, RDX, R8 и R9 |
__m128 |
Указатель.Первые 4 параметра, переданные в качестве указателей в RCX, RDX, R8 и R9 |
Пример передачи аргумента 1 — все целые числа
func1(int a, int b, int c, int d, int e);
// a in RCX, b in RDX, c in R8, d in R9, e pushed on stack
Пример передачи аргумента 2 — все с плавающей запятой
func2(float a, double b, float c, double d, float e);
// a in XMM0, b in XMM1, c in XMM2, d in XMM3, e pushed on stack
Пример передачи аргумента 3 — вперемешку целые и с плавающей запятой
func3(int a, double b, int c, float d);
// a in RCX, b in XMM1, c in R8, d in XMM3
Пример передачи аргумента 4 — __m64, __m128 и агрегатные параметры
func4(__m64 a, _m128 b, struct c, float d);
// a in RCX, ptr to b in RDX, ptr to c in R8, d in XMM3