На этом шаге мы рассмотрим проблему согласования параметров.
В таблице ниже представлены основные соглашения по передаче параметров в процедуру. Заметим в этой связи, что во всех наших ассемблерных программах мы указывали тип передачи параметров как stdcall. Однако, по сути, это никак и нигде не использовалось - так передача и извлечение параметров делалась нами явно, без помощи транслятора. Когда мы имеем дело с языками высокого уровня, необходимо представлять себе, как работают те или иные соглашения (таблица 1).
Соглашение | Параметры | Очистка стека | Регистры |
---|---|---|---|
Pascal (конвенция языка Паскаль) | Слева направо | Процедура | Нет |
Register (быстрый, или регистровый вызов) | Слева направо | Процедура | Задействованы три регистра (EAX, EDX, ECX), а затем стек |
Cdecl (конвенция языка C) | Справа налево | Вызывающая программа | Нет |
Ctdcall (стандартный вызов) | Справа налево | Процедура | Нет |
Таблица довольно ясно объясняет соглашения о передаче параметров, и здесь более добавить нечего.
Остановимся еще на весьма важном моменте - типе возвращаемых функцией данных. С точки зрения ассемблера здесь все предельно просто: в регистре ЕAX возвращается значение, которое может быть либо числом, либо указателем на некую переменную или структуру. Если возвращаемое число имеет тип WORD, то оно передается в младшем слове регистра ЕАХ. Однако, имея дело с C, вам надо очень аккуратно обращаться с такой проблемой, как преобразование типов. Преобразование типов - это целая наука, на которой мы не можем здесь останавливаться.
Более подробную информацию по преобразованию типов в C++ можно получить здесь.
На следующем шаге мы приведем простой пример использования ассемблера с языками высокого уровня.