Таблица 2-1
Соглашения о связях для языка Си фирмы "Майкрософт"
_______________________________________________________________
|
Соглашение | Описание
__________________________|____________________________________
|
Ссылка на программу | Near (близкие) или far (далекие)
Ссылки на данные | Near (близкие) или far (далекие)
Стек очищается | вызывающей программой
Параметры передаются в | обратном порядке
Параметры передаются по | значению
Значения возвращаются в | регистре AX или DX:AX
Длина имени | 8 символов
Всем именам предшествует | символ "подчеркивание" (_)
__________________________|____________________________________
Последним требованием к языку программирования Си является
возможность вызова программ на языке Ассемблер. Это требование
обеспечивается тем, что на языке Ассемблер функция должна быть
объявлена как public (общая), а на языке Си - как extern (внеш-
няя). Краткие сведения о соглашениях о связях для языка програм-
мирования Си фирмы "Майкрософт" приведены в таблице 2-1.
Соглашения о связях для языка Паскаль фирмы "Майкрософт"
Если листинг 2-8 приближается к синтаксису вызова для языка
Си фирмы "Майкрософт", то соглашения о связях для компилятора язы-
ка Паскаль фирмы "Майкрософт" лучше выражаются с помощью примера,
приведенного в листинге 2-4. Вызов на Паскале эквивалентен вызову
процедуры myproc (моя процедура), закодированному следующим обра-
зом:
procedure MyProc (Param1, Param2, Param3 : integer) ;
begin
...
Главное отличие между языками Си и Паскаль состоит в том, что
Паскаль выполняет гораздо больше строгих проверок. Эти проверки
гарантируют: что при вызове передается правильное количество и
типы параметров; что значения функции используются способом, со-
ответствующим их типу и т.д. Таким образом, в отличие от языка
Си, в языке Паскаль программа должна быть объявлена либо процеду-
рой (подпрограмма, которая не возвращает значения), либо функци-
ей.
Язык Паскаль также обеспечивает использование автоматических
переменных для памяти локальных данных. Как и в языке Си, в языке
- 2-35 -
Паскаль нет стандартных решений о назначении порядка локальных
переменных в стеке. Также, как и в языке Си, в Паскале память для
локальных переменных распределяется при вершине стека на входе в
вызываемую программу. Если процедура MyProc использует локальные
переменные LocIndx, LocChar и LocWord, то они должны будут ссы-
латься так, как показано в структуре StackFrame листинга 2-8.
Паскаль эквивалентен программе, похожей на ниже приведенную:
procedure MyProc (Param1, Param2, Param3 : integer) ;
var
LocIndx, LocWord : integer ;
LocChar [1..14] : character ;
begin
...
Из листинга 2-4 можно увидеть, что в отличие от языка Си,
язык Паскаль помещает свои аргументы в порядке, в котором они
объявляются, слева направо. Причина, по которой этот способ воз-
можен, состоит в том, что компилятор языка Паскаль гарантирует,
что все обращения, выдаваемые программой, обеспечивают правильное
количество и типы аргументов. Язык Паскаль просто не позволяет
передавать переменное количество параметров, поэтому порядок пе-
редачи, используемый в языке Си, не требуется в языке Паскаль.
Следствием строгой проверки вызова, выполняемой языком Пас-
каль, является то, что вызываемая программа всегда получает одно
и то же количество аргументов, позволяющее вызываемой программе
использовать инструкцию RET N для очистки стека, нежели зависеть
от вызывающей программы.
Другим сходством с языком Си является то, что язык Паскаль
обычно передает свои переменные по значению, однако, если требу-
ется, то переменные можно передавать по адресу, используя описа-
ние var (переменная).
Таблица 2-2
Соглашения о связях языка Паскаль фирмы "Майкрософт"
________________________________________________________________
|
Соглашение | Описание
______________________________|_________________________________
|
Программные ссылки | Far (далекие)
Ссылки на данные | Far (далекие)
Стек очищается | вызываемой программой ( RET N)
Параметры передаются в | порядке объявления
Параметры передаются по | значению
Значения возвращаются в | регистре AX или DX:AX
Длина имени | 8 символов
Все имена являются | нечувствительными к регистру
______________________________|_________________________________
В отличие от языка Си, компилятор языка Паскаль фирмы "Майкро-
софт" использует модуль памяти LARGE (большой), предполагающий
вызовы far (далекий) и ссылки по памяти far (далекие). Также, в
отличие от Языка Си, язык Паскаль распознает имена на любом ре-
гистре, несмотря на то, что функция языка Ассемблер должна быть
еще объявлена как public (общая), а ссылки языка Паскаль должны
быть объявлены как extern (внешние). Краткие сведения о соглаше-
- 2-36 -
ниях о связях в языке Паскаль фирмы "Майкрософт" приведены в таб-
лице 2-2.
Соглашения о связях языков Фортран и Бэйсик фирмы "Майкрософт"
Стандартные компиляторы языков программирования Бэйсик и
Фортран фирмы "Майкрософт" очень похожи на компилятор языка Пас-
каль фирмы "Майкрософт". Таблица 2-3 справедливо показывает, как
много имеется сходства при стандартных вызовах. Однако, имеются и
отличия. Главным отличием от соглашений о связях языка Паскаль
состоит в том, что и Бэйсик и Фортран передают свои аргументы по
ссылкам. Так как эти языки программирования передают адреса пере-
менных, любые манипуляции переменными, выполняемые вызываемой
программой, также изменяют значения переменных в вызывающей прог-
рамме.
В действительности, сходство между всеми четырьмя интерфейса-
ми означает, что как легко написать подпрограмму на языке Ассемб-
лер для Бэйсика и Фортрана, также легко и для Паскаля или языка
Си. Однако, в программах языков Бэйсик и Фортран для установки
правильного интерфейса требуются большие усилия.
Эквивалентом предложения extern (внешний) в языке Бэйсик яв-
ляется предложение DECLARE (объявить), в то время как в языке
Фортран требуется предложение INTERFACE (интерфейс). Каждое из
этих предложений информирует соответствующий компилятор о том,
что имя соответствующей программы должно находиться вне текущего
модуля. Для информирования компилятора о том, как сформатировать
и сгенерировать правильный вызов, могут потребоваться дополни-
тельные параметры. Соглашения о связях для языков Бэйсик и Форт-
ран фирмы "Майкрософт" приведены в таблице 2-3.
Таблица 2-3
Соглашения о связях для языков Бэйсик и Фортран
фирмы "Майкрософт"
___________________________________________________________
| | | |
| Соглашение | Бэйсик | Фортран |
|______________________|_________________|__________________|
| | | |
|Ссылки на программы |Far (далекий) |Far (далекий) |
|Ссылки на данные |Far (далекий) |Far (далекий) |
|Стек очищается | вызываемой программой (RET N) |
|Параметры передаются в| в порядке объявления |
|Параметры передаются |по адресу Far(да-|по адресам Near |
| |лекий) |(близкий)/Far (да-|
| | |лекий) |
|Значения возвращаются | регистре AX или DX:AX |
|Длина имени |40 символов |6 символов |
|Все имена представлены|на верхнем ре- |нечувствительны |
| |гистре |к регистру |
|______________________|_________________|__________________|
Модель сегмента фирмы "Майкрософт"
Версия 5.0 макроассемблера MASM фирмы "Майкрософт" дает воз-
можность программисту быстро указывать надлежащие имена сегментов
и устанавливать их для данного языка программирования с помощью
директивы MODEL. Даже без версии 5.0 установка надлежащего шабло-
- 2-37 -
на языка Ассемблер относительно проста. Все четыре языка програм-
мирования используют одинаковые первичные имена сегментов. Имя
кодового сегмента "_TEXT", а имя сегмента данных "_DATA". Для от-
дельных интерфейсов могут потребоваться дополнительные сегменты,
и многие модели компиляторов фирмы "Майкрософт" требуют, чтобы
стек помещался бы в сегмент данных. Однако, простой программе на
языке Ассемблер не нужно беспокоиться об этом, так как она может
просто отключить функционирование стека в вызывающей программе и
все необходимые установки будет поддерживать главная подпрограмма
языка высокого уровня.
2 0Назначение и использование локального ЗУ в памяти
Имеется три способа распределения памяти для переменных. Бу-
дем рассматривать локальное ЗУ (локальную память) в оперативной
памяти и локальную память в стеке. Сейчас рассмотрим локальное ЗУ
в распределяемой памяти. Распределяемая память должна получаться
из неиспользуемой памяти системы (часто называемой пулом памяти).
MS-DOS поддерживает функции, которые могут быть использованы для
распределения, перераспределения и установки размера блоков сис-
темной памяти. После распределения памяти программист может реа-
лизовать свою личную (персональную) схему управления памяти для
управления памятью в узком участке. Однако сейчас сконцентрируем
свое внимание на возможностях MS-DOS, начиная с функции 48h -
"распределить память".
После получения блока памяти, программа должна иметь возмож-
ность его адресации. Память, распределяемая MS-DOS, предоставля-
ется в "кусках" по 16 байтов, называемых "paragraph" (парагра-
фом). MS-DOS возвращает указатель на эту память, которая содержит