Процедуры в языке ассемблера
В Ассемблере для оформления процедур как отдельных объектов существуют спе-
циальные директивы
и машинная команда
(см. главу 10).
срав-
нивать процедуры и макрокоманды, то можно сказать следующее. Процедуры, так
же как и макрокоманды, могут быть активизированы в любом месте программы.
328 Глава
Модульное программирование
Процедурам, так же как и макрокомандам, могут быть переданы некоторые аргу-
менты. Это позволяет, имея одну копию кода в памяти, изменять ее для каждого
конкретного случая использования, хотя по гибкости процедуры уступают макро-
командам.
В главе 10 нами были рассмотрены возможные варианты размещения процедур
в программе:
в начале программы (до первой исполняемой команды);
в конце программы (после команды, возвращающей управление операционной
системе);
промежуточный вариант — тело процедуры располагается внутри другой про-
цедуры или основной программы (в этом случае необходимо предусмотреть
обход процедуры с помощью команды безусловного перехода JMP);
* в другом модуле.
Главная цель таких вариантов размещения — не допустить несанкционирован-
ной передачи управления коду процедуры. Три первых варианта относятся к слу-
чаю, когда процедуры находятся в одном сегменте кода. Мы их достаточно подробно
обсудили. Что же касается последнего варианта, то он предполагает, что процеду-
ры находятся в разных модулях. А это дает нам возможность говорить уже не об
одном модуле, а о нескольких. Для реализации одной общей задачи эти модули
должны быть связаны между собой по управлению и по данным. Если мы разбе-
ремся с тем, как организовать такую связь, то фактически сможем выполнить функ-
циональную декомпозицию любой большой программы на нужное количество
более мелких. В первой части главы мы рассмотрим, как организуется связь по
управлению и по данным между модулями на ассемблере, во второй части — меж-
ду модулями на ассемблере и на языках высокого уровня (Pascal и C/C++).
Сначала необходимо отметить один общий для всех этих трех языков момент.
Так как отдельный модуль в соответствии с концепцией модульного программи-
рования — это функционально автономный объект, то он ничего не должен знать
о внутреннем устройстве других модулей, и наоборот, другим модулям также ни-
чего не должно быть известно о внутреннем устройстве данного модуля. Однако
должны быть какие-то средства, с помощью которых можно связать модули. В ка-
честве аналогии можно привести организацию связи (интерфейс) телевизора и ви-
деомагнитофона через разъем типа
Связь унифицирована, то есть извест-
но, что один контакт предназначен для видеосигнала, другой — для передачи звука
и т. д. Телевизор и видеомагнитофон могут быть разными, но связь между ними
одинакова. Та же идея лежит и в организации связи модулей. Внутреннее устрой-
ство модулей может совершенствоваться, они вообще могут в следующих версиях
писаться на другом языке, но в процессе их объединения в единый исполняемый
модуль этих особенностей не должно быть заметно. Таким образом, каждый мо-
дуль должен иметь такие средства, с помощью которых он извещал бы транслятор
о том, что некоторый объект (процедура, переменная) видимым вне этого модуля.
И наоборот, нужно объяснить транслятору, что некоторый объект находится вне
данного модуля. Это позволит транслятору правильно сформировать машинные
команды, оставив некоторые их поля не заполненными.
на этапе компо-
Процедуры в языке ассемблера 329
новки, программа
(TASM) или программа компоновки языка высокого
уровня произведут настройку модулей и разрешат все внешние ссылки в объеди-
няемых модулях.
Для того чтобы объявить о подобного рода объектах, видимых извне, програм-
ма должна использовать две директивы TASM: EXTRN и PUBLIC. Директива EXTRN
предназначена для объявления некоторого имени внешним по отношению к дан-
ному модулю. Это имя в другом модуле должно быть объявлено в директиве
Директива PUBLIC предназначена для объявления некоторого имени, определен-
ного в этом модуле и видимого в других модулях. Синтаксис этих директив следу-
ющий:
e x t r n
public
Здесь имя — идентификатор, определенный в другом модуле. В качестве иден-
тификатора могут выступать:
имена переменных, определенных директивами типа DB, DW и т. д.;
ж имена процедур;
имена констант, определенных операторами = и EQU.
Аргумент
определяет тип идентификатора. Указание типа необходимо для
того, чтобы транслятор правильно сформировал соответствующую машинную ко-
манду. Действительные адреса вычисляются на этапе редактирования, когда бу-
дут разрешаться внешние ссылки. Возможные значения типа определяются допу-
стимыми типами объектов для этих директив:
в если имя — это имя переменной, то тип может принимать значения BYTE, WORD,
DWORD, PWORD, FWORD, QWORD и
если имя — это имя процедуры, то тип может принимать значения near или far;
li если имя — это имя
то тип должен быть abs.
Покажем принцип использования директив EXTRN и PUBLIC на схеме связи мо-
дулей 1 и 2 (листинги 15.1 и 15.2).
Листинг
Модуль 1
1
small
256
proc
my_proc_2
процедуру
видимой извне
public
s t a r t :
end s t a r t
330 Глава
Модульное программирование
Do'stlaringiz bilan baham: |