Описание языка процедуры
Вы можете легко определить процедуры, которые используют в Турбо Ассемблере соглашения по интерфейсу языков высокого уровня. Соглашения по интерфейсу поддерживаются для языков NOLANGUAGE (Ассемблер), BASIC, PROLOG, FORTRAN, C, CPP (C++) и PASCAL.
Турбо Ассемблер выполняет всю работу по генерации корректно- го кода начала (вход в процедуру) и завершения (выход из процеду- ры), необходимых для соблюдения соглашений заданного языка.
С помощью директивы MODEL вы можете задать язык, используе- мый по умолчанию. Подробности можно найти в Главе 7. Если используемый по умолчанию язык задан, все процедуры, для которых не задается другой язык, используют соглашения назначенного по умолчанию языка.
Чтобы переопределить используемый по умолчанию язык для конкретной процедуры, включите имя языка в определение процедуры. Вы можете задать язык процедуры, включив описывающее язык ключе- вое слово в описание процедуры. Например, определение в режиме MASM процедуры PASCAL может иметь вид:
. . . pascalproc PROC PASCAL FAR ; тело процедуры pascalproc ENDP . . .
Турбо Ассемблер использует заданный в процедуре язык для оп- ределения того, какой вход начала и завершения нужно автоматичес- ки включить в тело процедуры. Начальный код устанавливает кадр стека для передаваемых аргументов и локальных переменных процеду- ры, а код завершения перед возвратом из процедуры восстанавливает кадр стека.
Турбо Ассемблер автоматически вставляет в процедуру началь- ный код перед первой инструкцией процедуры или перед первой мет- кой ("метка: цель").
В коде завершения делается следующее:
- в стеке сохраняется текущий регистр BP;
- BP настраивается на текущий указатель стека;
- настраивается указатель стека для выделения локальных пе- ременных;
- в стеке сохраняются регистры, заданные спецификатором USES.
По каждой инструкции RET процедуры Турбо Ассемблер автома- тически вставляет в процедуру код завершения (в случае нескольких инструкций RET код завершения будет вставляться несколько раз). Турбо Ассемблер также вставляет код завершения перед переходом на любой объектно-ориентированный метод (см. Главу 4).
Завершающий код изменяет действие кода инициализации на об- ратное. Это делается следующий образом:
- из стека извлекаются регистры, заданные оператором USES;
- настраивается указатель стека, чтобы отбросить локальные аргументы;
- из стека извлекается сохраненный регистр BP;
- стек настраивается, чтобы отбросить переданные аргументы (если этого требует язык) и выполнить возврат.
Последний шаг кода завершения (отбрасывание аргументов) вы- полняется только для тех языков, которые требуют удаления аргу- ментов процедуры (например, Бейсик, Фортран, Паскаль). По согла- шениям, принятым в других языках (Си, С++, Пролог), аргументы ос- таются в стеке, и удалять их должна вызывающая программа.
Турбо Ассемблер всегда реализует код начала и завершения процедуры с помощью наиболее эффективных инструкций текущего выб- ранного языка и процессора.
Для процедур NOLANGUAGE Турбо Ассемблер не генерирует код начала и завершения. Если в таких процедурах ожидается передача аргументов в стеке, вы должны сами включать код начала и заверше- ния.
В общем случае язык процедуры влияет на процедуру следующим образом:
Как язык влияет на процедуру 10.1 ----------T------T------T--------T--------T-------T------T------¬ ¦ Язык ¦ Нет ¦Бейсик¦ Фортран¦ Паскаль¦ Си ¦ С++ ¦Пролог¦ +---------+------+------+--------+--------+-------+------+------+ ¦ Порядок ¦ L-R ¦ L-R ¦ L-R ¦ L-R ¦ R-L ¦ R-L ¦ R-L ¦ ¦ аргу- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ментов ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ (слева ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ -напра- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ во, ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ справа- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ налево) ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ +---------+------+------+--------+--------+-------+------+------+ ¦Кто очи- ¦проце-¦проце-¦процеду-¦процеду-¦вызыва-¦вызы- ¦вызы- ¦ ¦щает стек¦дура ¦дура ¦ра ¦дура ¦ющая ¦вающая¦вающая¦ ¦(вызыва- ¦ ¦ ¦ ¦ ¦прог- ¦прог- ¦прог- ¦ ¦ющая ¦ ¦ ¦ ¦ ¦рамма ¦рамма ¦рамма ¦ ¦программа¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦или про- ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦цедура) ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ L---------+------+------+--------+--------+-------+------+-------
L-R - слева-направо, R-L - справа-налево.
Для включения в файл листинга кода начала и завершения вы можете использовать параметр командной строки /la. Это позволит вам увидеть разницу между языками.
Примечание: Более подробную информацию можно найти в Главе 13.
Содержание раздела