Страница 46 из 56
Какие проблемы могут возникнуть при использовании Пас-
каль-соглашения по вызову?
Во-первых, оно не так сильно, как Си-соглашение по вызову.
Вы не можете передать переменное число параметров (что возможно в
случае Си-соглашения), т.к. вызванная подпрограмма должна знать,
сколько параметров заносится в стек и, соответственно, извлекает-
ся из него. Передача слишком малого или слишком большого коли-
чества параметров будет приводить к серьезным трудностям, в то
время как при Си-соглашении это не даст нежелательного эффекта
(за исключением, возможно, неверных ответов).
Во-вторых, если вы используете -р опцию транслятора, то вы
должны обязательно включить файлы заголовков для стандартных
Си-функций, которые вы вызываете. Это необходимо потому, что если
вы этого не сделаете, Турбо Си будет использовать Паскаль-согла-
шение для вызова каждой из этих функций, и ваша программа навер-
няка потерпит крах, потому что:
1) параметры будут в неверном порядке;
- 377,378 -
2) ничем не будет очищаться стек.
Файлы заголовков объявляют каждую из таких функций как
cdecl, поэтому, если вы включете их, транслятор увидит это и бу-
дет использовать Си-соглашение по стеку. Однако, т.к. идентифика-
торы cdecl дополняются символом подчеркивания, в отличие от иден-
тификаторов Pascal, то при компоновке вы получите множество
ошибок, если не установите режим Generate undebars "Off". Потом у
вас будут большие неприятности.
Заключение: если вы собираетесь использовать Паскаль-согла-
шение по вызову в программе Турбо Си, то убедитесь, что каждая
функция явно объявлена как cdecl или pascal. Это очень полезно в
случае использования опции компиляции о требовании наличия прото-
типа, т.к. в этом случае вы можете быть уверены, что каждая функ-
ция вызывается строго в соответствии с ее прототипом.
Интерфейс с языком ассемблера
-----------------------------------------------------------------
Теперь вы знаете, как работает каждое соглашение по вызову и
что в этом случае делает компилятор Турбо Си. Что же вам необхо-
димо делать в вызываемой подпрограмме? Расмотрим это на примере
написанной на ассемблере подпрограммы, которую можно вызывать из
Турбо Си.
Замечание: в этом разделе мы подразумеваем, что вы знаете,
как писать программы на языке ассемблера для 8086 и как опреде-
лять сегменты, константы данных и т.п. Если вы не знакомы с этими
вопросами, то можете ознакомиться с ними в Turbo Assembler
Reference Guide.
Порядок вызова ассемблера из Турбо Си
-----------------------------------------------------------------
Вы можете написать подпрограммы на языке ассемблера в виде
модулей и скомпоновать их с вашими программами на Си. Однако име-
- 379,380 -
ются определенные соглашения, которым вы должны следовать:
1) убедиться, что компоновщик может получить необходимую ин-
формацию;
2) убедиться, что формат файла согласуется с типом модели
памяти, используемой в вашей программе на Си.
Ниже приведена общая схема программы:
=filname_DATA
ННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННННН
- 383,384 -
Таблица 12.5. Идентификаторы замещения и модели памяти
Определение констант данных и переменных
-----------------------------------------------------------------
Выбор модели памяти влияет также на способ определения конс-
тант данных, являющихся указателями к программе, данным или к то-
му и другому сразу. Табл.12.5 показывает, как будут выглядеть,эти
указатели. Здесь ххх - адрес, являющийся указателем.
Обратите внимание на то, что одни указатели используют ко-