Поделиться через


Передача параметров

Обновлен: Ноябрь 2007

Первые четыре аргумента целых чисел передаются в регистры. Значения целых чисел передаются (слева направо) в RCX, RDX, R8 и R9. Остальные аргументы (после первых четырех) передаются в стек. Все аргументы в регистрах выравниваются по правому краю. Это делается для того, чтобы вызываемый мог игнорировать старшие разряды регистра при необходимости и получить доступ только к необходимой части регистра.

Аргументы значений с плавающей запятой и двойной точностью передаются в XMM0 – XMM3 (до 4) с помощью гнезда целых чисел (RCX, RDX, R8 и R9), которое обычно и используется, в то время как гнездо кардинальных чисел отклоняется (см. пример) и наоборот.

__m128 типы, массивы и строки никогда не передаются в виде непосредственных значений, а передаются как указатель на область памяти, выделенную вызывающим. 8, 16, 32 или 64-разрядные структуры/объединения и указатель _m64 передаются, как если они были бы целыми числами одинакового размера. Структуры/объединения других размеров должны передаваться как указатель на область памяти, выделенную оператором. Для этих агрегатных типов, передаваемых в качестве указателя (включая __m128), память должна быть выровнена по 16 разряду.

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

Вызываемый несет ответственность за сбрасывание при необходимости параметров регистра в теневое пространство.

В следующей таблице подведены итоги передачи параметров:

Тип параметра

Передача

С плавающей запятой

Первые 4 параметра — от XMM0 к XMM3. Остальные передаются в стек.

Целое число

Первые 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

См. также

Ссылки

Соглашение о вызовах