На этом шаге мы рассмотрим организацию межсегментных вызовов.
Современные программные проекты состоят, как правило, из нескольких модулей, каждый из которых содержит свою часть программы. Так как отдельный модуль в соответствии с концепцией модульного программирования - это функционально автономный объект, то он ничего не должен знать о внутреннем устройстве других модулей, и наоборот, другим модулям также ничего не известно о внутреннем устройстве данного модуля. Но должны быть какие-то средства, с помощью которых можно связать модули в одно целое.
Таким образом, каждый модуль должен иметь такие средства, с помощью которых он извещал бы транслятор о том, что некоторый объект (процедура, переменная) должен быть видимым вне этого модуля. И наоборот, нужно объяснить транслятору, что некоторый объект находится вне данного модуля. Это позволит транслятору правильно сформировать машинные команды, оставив некоторые их поля незаполненными. Позднее, на этапе компоновки, программа компоновки произведет настройку модулей и разрешит все внешние ссылки в объединяемых модулях.
Для того чтобы объявить о подобного рода видимых извне объектах, программа должна использовать две директивы EXTRN и PUBLIC. Директива EXTRN предназначена для объявления некоторого имени внешним по отношению к данному модулю. Это имя в другом модуле должно быть объявлено в директиве PUBLIC. Директива PUBLIC предназначена для объявления некоторого имени, определенного в этом модуле, видимым также в других модулях. Синтаксис этих директив следующий:
EXTRN <имя1: тип1>, ..., <имяN: типN> PUBLIC <имя1>, ...,<имяN> .
Здесь имя - идентификатор, определенный в другом модуле. В качестве идентификатора могут выступать:
Тип определяет тип идентификатора. Указание типа необходимо для того, чтобы транслятор правильно сформировал соответствующую машинную команду. Действительные адреса будут вычислены на этапе редактирования, когда будут разрешаться внешние ссылки. Возможные значения типа определяются допустимыми типами объектов для этих директив:
;Модуль 1 PUBLIC my_proc_1 ;Объявляем процедуру видимой извне. . . . . . Codesg SEGMENT PARA PUBLIC my_proc_1 PROC FAR ;Данное значение расстояния указывает, что ;при возврате из процедуры из стека будет ;извлечено два слова. . . . . . my_proc_1 ENDP my_proc_2 PROC . . . . . my_proc_2 ENDP Codesg ENDS END ;Модуль 2 EXTRN my_proc_1: Far ;Объявляем процедуру внешней. ;Заданный тип указывает, что при обращении ;к процедуре в стек в качестве адреса возврата ;будет помещено два слова. . . . . . Codesg SSGMENT PARA PUBLIC Begin PROC FAR . . . . . CALL my_proc_1 ;Вызов процедуры из модуля 1. . . . . . Begin ENDP Codesg ENDS END Begin
Рассмотренная нами схема связи - это, фактически, связь по управлению. Но не менее важно организовать информационный обмен между модулями. Рассмотрим основные способы организации такой связи.
На следующем шаге мы рассмотрим способы передачи данных в процедуру.