Описание языка процедуры
Вы можете легко определить процедуры, которые используют в Турбо Ассемблере соглашения по интерфейсу языков высокого уровня. Соглашения по интерфейсу поддерживаются для языков NOLANGUAGE (Ассемблер), BASIC, PROLOG, FORTRAN, C, CPP (C++) и PASCAL.
Турбо Ассемблер выполняет всю работу по генерации корректного кода начала (вход в процедуру) и завершения (выход из процедуры), необходимых для соблюдения соглашений заданного языка.
С помощью директивы MODEL вы можете задать язык, используемый по умолчанию. Подробности можно найти здесь. Если используемый по умолчанию язык задан, все процедуры, для которых не задается другой язык, используют соглашения назначенного по умолчанию языка.
Чтобы переопределить используемый по умолчанию язык для конкретной процедуры, включите имя языка в определение процедуры. Вы можете задать язык процедуры, включив описывающее язык ключевое слово в описание процедуры. Например, определение в режиме MASM процедуры PASCAL может иметь вид:
. . . pascalproc PROC PASCAL FAR ; тело процедуры pascalproc ENDP . . .
Турбо Ассемблер использует заданный в процедуре язык для определения того, какой вход начала и завершения нужно автоматически включить в тело процедуры. Начальный код устанавливает кадр стека для передаваемых аргументов и локальных переменных процедуры, а код завершения перед возвратом из процедуры восстанавливает кадр стека.
Турбо Ассемблер автоматически вставляет в процедуру начальный код перед первой инструкцией процедуры или перед первой меткой ("метка: цель").
В коде завершения делается следующее:
в стеке сохраняется текущий регистр BP;
BP настраивается на текущий указатель стека;
настраивается указатель стека для выделения локальных переменных;
в стеке сохраняются регистры, заданные спецификатором USES.
По каждой инструкции RET процедуры Турбо Ассемблер автоматически вставляет в процедуру код завершения (в случае нескольких инструкций RET код завершения будет вставляться несколько раз). Турбо Ассемблер также вставляет код завершения перед переходом на любой объектно-ориентированный метод (см. здесь).
Завершающий код изменяет действие кода инициализации на обратное. Это делается следующий образом:
из стека извлекаются регистры, заданные оператором USES;
настраивается указатель стека, чтобы отбросить локальные аргументы;
из стека извлекается сохраненный регистр BP;
стек настраивается, чтобы отбросить переданные аргументы (если этого требует язык) и выполнить возврат.
Последний шаг кода завершения (отбрасывание аргументов) выполняется только для тех языков, которые требуют удаления аргументов процедуры (например, Бейсик, Фортран, Паскаль). По соглашениям, принятым в других языках (Си, С++, Пролог), аргументы остаются в стеке, и удалять их должна вызывающая программа.
Турбо Ассемблер всегда реализует код начала и завершения процедуры с помощью наиболее эффективных инструкций текущего выбранного языка и процессора.
Для процедур NOLANGUAGE Турбо Ассемблер не генерирует код начала и завершения. Если в таких процедурах ожидается передача аргументов в стеке, вы должны сами включать код начала и завершения.
В общем случае язык процедуры влияет на процедуру следующим образом:
Как язык влияет на процедуруЯзык | Нет | Бейсик | Фортран | Паскаль | Си | С++ | Пролог |
---|
Порядок аргументов (слева-направо, справа-налево) | L-R | L-R | L-R | L-R | R-L | R-L | R-L | Кто очищает стек (вызывающая программа или процедура) | процедура | процедура | процедура | процедура | вызывающая программа | вызывающая программа | вызывающая программа |
L-R - слева-направо, R-L - справа-налево.
Для включения в файл листинга кода начала и завершения вы можете использовать параметр командной строки /la. Это позволит вам увидеть разницу между языками.
Примечание: Более подробную информацию можно найти здесь
Задание модификатора языка
Модификаторы языка указывают сообщают Турбо Ассемблеру, что в процедуры нужно включать специальный код начала и завершения, организующий интерфейс с Windows и менеджером оверлеев VROOM. Чтобы эти модификаторы использовать, укажите их перед языком процедуры в директиве модели или в заголовке процедуры. Допустимыми модификаторами являются модификаторы NORMAL, WINDOWS, ODDNEAR и ODDFAR.
Кроме того, вы можете задать используемый по умолчанию модификатор языка в качестве параметра директивы MODEL. Если используемый по умолчанию модификатор языка присутствует, то все процедуры, в которых не задается модификатор языка, будут использовать соглашения, заданные по умолчанию.
Примечание: Подробнее об этом рассказывается в этой главе
Чтобы задать модификатор языка для конкретной процедуры, включите модификатор языка в конкретную процедуру. Например:
. . . sample PROC WINDOWS PASCAL FAR ENDP . . .
Если вы не задаете модификатор языка, Турбо Ассемблер использует модификатор языка, заданный в операторе MODEL. Если директива MODEL отсутствует, или если задан модификатор NORMAL, то Турбо Ассемблер будет использовать стандартный код начала и завершения.
Если вы выбрали модификатор языка WINDOWS, Турбо Ассемблер генерирует код начала и завершения, позволяющий вам выбирать процедуру из Windows. Турбо Ассемблер генерирует специальный код начала и завершения только для процедура FAR WINDOWS. Из Windows вы не можете вызвать процедуры NEAR, поэтому специальный код начала и завершения для них не требуется. Процедуры, вызываемые Windows, обычно используют соглашения по вызову, принятые в Паскале (PASCAL). Например:
. . . Winoproc PROC WINDOWS PASCAL FAR ARG __hwnd:WORD, __mess:WORD, __wparam:WORD, __lparam:DWORD ; тело процедуры ENDP . . .
Примечание: Подробности о процедурах Windows можно узнать в документации по Windows.
Модификаторы языка ODDNEAR и ODDFAR используются для менеджера оверлеев VROOM. VROOM имеет два режима операций: oddnear и oddfar. Чтобы увидеть код начала и завершения, который порождают эти модификаторы, вы можете использовать параметр командной строки /la.
1 2 3 4 5
8 8 8
| |