Учет особенностей компилятора
При разработке ассемблерных процедур для программных модулей, составленных на алгоритмических языках, должны быть выполнены два условия. Во-первых, процедура должна поддерживать ту форму интерфейса с вызывающим модулем, которая принята в конкретном алгоритмическом языке. Во-вторых, она должна быть описана так, чтобы компилятор с выбранного вами языка мог составить нужную последовательность команд для ее вызова. Другими словами, вызывающий модуль и процедура должны соответствовать друг другу. Кроме того, обязательно должна оставаться возможность вызова из модуля, составленного на языке Макроассемблера. Она нужна, по крайней мере, для предварительной отладки и желательно, чтобы после отладки основной текст процедуры не изменялся.
Учитывая практическую важность сказанного в состав Макроассемблера, начиная с MASM 6.0, включены специальные средства для описания подпрограмм и оформления их вызова. В данном разделе приведен краткий обзор этих средств и пример их использования. При этом автор стремился выделить наиболее важные вопросы, ответ на которые не всегда очевиден.
В полный комплект поставки MASM 6.0 и последующих версий входит подробный HELP, содержащий описание директив, операторов и прочих атрибутов языка. Работая с Макроассемблером, вы всегда можете получить дополнительные сведения по интересующему вас вопросу.
Различие алгоритмических языков
Алгоритмические языки созданы и создаются для решения различных классов или категорий задач, поэтому они принципиально отличаются друг от друга. Здесь нас интересуют только те различия, которые относятся к действиям, связанным с вызовом процедур. Основная часть вызова процедуры в большинстве алгоритмических языков имеет следующий вид:
имя_процедуры (список_параметров)
Однако соответствующая ей последовательность команд зависит от конкретных особенностей компилятора. Прежде всего, в именах процедуры и параметров могут различаться или не различаться заглавные и строчные буквы. Далее, параметры могут записываться в стек в порядке их перечисления в списке или в обратном порядке. Количество параметров в списке может быть фиксированным или переменным. Наконец, параметры могут удаляться из стека при возврате из процедуры или в вызывающем модуле.
В табл. В.3 перечислены особенности компиляторов, свойства которых может учитывать Макроассемблер при компиляции программных модулей.
Таблица В.3.
С | Sy | St | В | F | Р | |
---|---|---|---|---|---|---|
Различаются строчные и заглавные | Да | Да | Да | Нет | Нет | Нет |
Строчные буквы в именах преобразуются | Нет | Нет | Нет | Да | Да | Да |
Параметры записываются в стек в порядке их перечисления в списке | Нет | Нет | Нет | Да | Да | Да |
Параметры записываются в стек в обратном | Да | Да | Да | Нет | Нет | Нет |
Параметры удаляются в процедуре при выполнении команды ret | Нет | Нет | * | Да | Да | Да |
Параметры удаляются в вызывающем модуле (команда add sp, N) | Да | Да | * | Нет | Нет | Нет |
Допустим список параметров переменной длины (тип varagr) | Да | Да | Да | Нет | Нет | Нет |
В табл. В.З использованы следующие сокращения имен языков: С – Си, Sy – Syscall, St – Stdcall, В – Basic (Бейсик), F – Fortran (Фортран), Р – Pascal (Паскаль).
Пояснять смысл имен Си, Бейсик, Фортран и Паскаль нет необходимости. Слова Syscall и Stdcall не соответствуют ни одному из конкретных языков, их точное назначение в HELP не описано, об этом можно только догадываться. Звездочки в столбце St обозначают, что место удаления параметров зависит от формы задания их списка. При обычной форме вызова их удаляет процедура, а если количество параметров переменное, то они удаляются в вызывающем модуле.
Для того чтобы Макроассемблер учитывал при компиляции программного модуля перечисленные в табл. В.3 особенности, у директив MODEL, PROC и PROTO (см. ниже) появился новый спецификатор Langtype. Его допустимыми значениями являются имена С, Syscall, Stdcall, Basic, Fortran и Pascal. Имя должно быть указано явно, умолчаний не существует.
Замечание
При описании названий языков в тексте книги мы также указываем русскую транскрипцию их названий, но в записи параметров на языке Макроассемблера используются только латинские имена.