Связь между подпрограммами
МЕТОДИЧЕСКИЕ УКАЗАНИЯ:
1. Для выполнения лабораторной работы вы должны войти в каталог группы из панели NORTON. Каждый студент должен иметь в каталоге группы свой личный каталог. Все программы должны создаваться и записываться в личном каталоге студента.
2. В общем случае программы строятся из основной программы и одной или более подпрограмм. Причины такой организации программ состоят в следующем:
- бывает необходимо скомпоновать программы, написанные на разных языках, например для объединения мощности языка высокого уровня и эффективности ассемблера;
- программа, написанная в виде одного модуля, может оказаться слишком большой для ассемблирования;
- отдельные части программы могут быть написаны разными группами программистов, ассемблирующих свои модули раздельно;
Каждая программа ассемблируется (tasm.exe) отдельно и генерирует собственный уникальный объектный (obj) модуль. Программа-компоновщик (tlink.exe) затем компонует объектные модули в один объектный выполняемый (exe или com) модуль.
3. Команды CALL могут осуществлять внутрисегментный (короткий) вызов подпрограммы или межсегментный (длинный) вызов подпрограммы.
Внутрисегментный вызов осуществляется в пределах от +127 до -128 байт. Команда CALL при этом может иметь, например, следующий объектный код Е82000. Где Е8 это код операции вызова подпрограммы, 2000 это относительный адрес 0020, который заносится в регистр IP. Микропроцессор объединяет адрес текущего сегмента в регистре CS и относительный адрес в регистре IP и получает фактический адрес по которому расположена первая команда вызываемой
подпрограммы. Старое значение регистра IP по команде CALL запоминается в стеке. При возврате из подпрограммы команда RET восстанавливает из стека старое значение в регистре IP и передает управление таким образом на следующую после команды CALL команду в основной программе.
Межсегментный вызов осуществляется в случае превышения пределов +127 ... -128 байт. Данная операция сначала записывает в стек содержимое регистра CS и заносит в этот регистр адрес другого сегмента, затем записывает в стек значение регистра IP и заносит новый относительный адрес в этот регистр. Таким образом, в стеке запоминаются и адрес кодового сегмента, и смещение для последующего возврата из подпрограммы.
Например, межсегментный вызов CALL может состоять из следующего объектного кода:
9А 0002 AF04
где 9А это код команды межсегментного вызова, 0002 это относительный адрес 0200, который записывается в регистр IP, AF04 это адрес нового кодового сегмента 04AF, который записывается в регистр CS. Сумма этих адресов определяет фактический адрес первой команды вызываемой подпрограммы:
Кодовый сегмент 04AF0
+
Смещение в IP 0200
-----
Фактический адрес 04CF0
При выходе из подпрограммы межсегментная команда RET восстанавливает оба адреса в регистрах CS и IP и таким образом передает управление на следующую после CALL команду основной программы.
4. Рассмотрим основную программу (MAINPROG), которая вызывает подпрограмму (SUBPROG) с помощью межсегментного вызова CALL:
EXTRN SUBPROG:FAR
MAINPROG: .
.