Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практичне заняття № 4 МЗКІТ (рус, дороб) (10 ТП).DOCX
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
6.04 Mб
Скачать

Процедуры в языке асемблера

В языке ассемблера для оформления процедур как отдельных объектов существуют специальные директивы PR0C/EN0P и машинная команда ret. Процедуры, так же как и макрокоманды, ценны тем, что могут быть активизированы в любом месте программы. Процедурам, так же как и макрокомандам, могут быть переданы некоторые аргументы, что позволяет, имея одну копию кода в памяти, изменять ее для каждого конкретного случая использования, хотя по гибкости использования процедуры уступают макрокомандам. Особых проблем с разработкой и применением процедур нет. Возможные варианты размещения процедур в программе:

  • в начале программы (до первой исполняемой команды);

  • в конце (после команды, возвращающей управление операционной системе);

  • промежуточный вариант — тело процедуры располагается внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход процедуры с помощью команды безусловного перехода jmp;

  • в другом модуле.

Главное условие здесь то, чтобы на процедуру не попадало управление. Три первых варианта из этих четырех относятся к случаю, когда процедуры находятся в одном сегменте кода. Что же касается последнего варианта, то он предполагает, что процедуры находятся в разных модулях. А это дает нам возможность говорить уже не об одной программе, а о нескольких. Эти программы должны быть связаны между собой по управлению и по данным. Если мы разберемся с тем, как организовать такую связь, то фактически сможем выполнить функциональную декомпозицию любой большой программы на несколько более мелких. Рассмотрим, как организуется связь по управлению и по данным между программами на ассемблере. Потом мы разберем связь между программами на ассемблере, Pascal и С.

Сначала необходимо отметить один общий для всех этих трех языков момент. Так как отдельный модуль в соответствии с концепцией модульного программирования — это функционально автономный объект, то он ничего не должен знать о внутреннем устройстве других модулей, и наоборот, другим модулям также ничего не известно о внутреннем устройстве данного модуля. Но должны быть какие-то средства, с помощью которых можно связать модули. В качестве аналогии можно привести известную вам организацию связи телевизора и видеомагнитофона через разъем типа «скарт». Связь унифицирована, то есть известно, что один контакт предназначен для видеосигнала, другой — для передачи звука и т. д. Телевизор и видеомагнитофон могут быть разными, но связь между ними одинакова. Та же идея лежит и в организации связи модулей. Внутреннее устройство модулей может совершенствоваться, они вообще могут в следующих версиях писаться на другом языке, но в процессе их объединения в единый исполняемый модуль этих особенностей не должно быть заметно. Таким образом, каждый модуль должен иметь такие средства, с помощью которых он извещал бы транслятор о том, что некоторый объект (процедура, переменная) должен быть видимым вне этого модуля. И наоборот, нужно объяснить транслятору, что некоторый объект находится вне данного модуля. Это позволит транслятору правильно сформировать машинные команды, оставив некоторые их поля незаполненными. Позднее, на этапе компоновки, программа TLINK или программа компоновки языка высокого уровня произведет настройку модулей и разрешит все внешние ссылки в объединяемых модулях.

Для того чтобы объявить о подобного рода видимых извне объектах, программа должна использовать две директивы TASM: extrn и public. Директива extrn предназначена для объявления некоторого имени внешним по отношению к данному модулю. Это имя в другом модуле должно быть объявлено в директиве public. Директива public предназначена для объявления некоторого имени, определенного в этом модуле, и видимым в других модулях.

Синтаксис этих директив следующий:

Здесь имя — идентификатор, определенный в другом модуле. В качестве идентификатора могут выступать:

  • имена переменных, определенных директивами типа db, dw и т. д.;

  • имена процедур;

  • имена констант, определенных операторами = и equ.

Тип определяет тип идентификатора. Указание типа необходимо для того, чтобы транслятор правильно сформировал соответствующую машинную команду. Действительные адреса будут вычислены на этапе редактирования, когда будут разрешаться внешние ссылки. Возможные значения типа определяются допустимыми типами объектов для этих директив:

если имя — это имя переменной, то тип может принимать значения byte, word, dword, pword, fword, qword и tbyte;

если имя —это имя процедуры, то тип может принимать значение near или faг;

если имя — это имя константы, то тип должен быть abs.

Покажем принцип использования директив extrn и public на схеме связи двух модулей Модуль 1 и Модуль 2 (см. листинги 14.1 и 14.2).

Листинг 14.1. Модуль 1

Листинг 14.2. Модуль 2

Рассмотренная нами схема связи — это, фактически, связь по управлению. Но не менее важно организовать информационный обмен между модулями. Рассмотрим основные способы организации такой связи.