Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
46
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 3

сохраняет все регистры программы, а перед возвратом в программу их восстанавливает. Поэтому, вызывая функции DOS (или BIOS) можно не заботиться о сохранении регистров — их содержимое система на разруша­ет. Надо только иметь в виду, что многие функции DOS и BIOS после своего завершения возвращают в программу некоторую информацию (чис­ло реально введенных символов, доступный объем памяти, номер видео­режима и т.п.). Обычно эта информация возвращается в регистре АХ, од­нако могут использоваться и другие регистры или их сочетания. Поэтому, обращаясь в программе к системным функциям, необходимо ознакомиться с их описанием и, в частности, посмотреть, какие регистры они могут использовать для возвращаемых значений.

Запустив программу, можно убедиться в том, что строки текста появ­ляются на экране через заметные промежутки времени.

В примере 3-8 подпрограмма не требовала параметров. Чаще, однако, подпрограмма должна принимать один или несколько параметров и воз­вращать результат. В этом случае необходимо организовать взаимодействие основной программы и подпрограммы. Никаких специальных средств языка для этого не существует; передачу параметров в подпрограмму и из нее программист организует по своему усмотрению. Для передачи параметров как в одну, так и в другую сторону можно использовать регистры общего назначения, ячейки памяти или стек. Например, нетрудно преобразовать подпрограмму delay из примера 3-8 так, чтобы ей можно было передавать величину требуемой задержки. Пусть эта величина (в члсле шагов внешне­го цикла) передается в регистре SI.

;Пример 3-8а.Подпрограмма задержки с одним параметром,

передаваемом в регистре SI

delay

proc

; Процедура - подпрограмма

push

CX

;Сохраним СХ основной программы

mov

CX,SI

;Счетчик внешнего цикла

dell:

push

CX

;Сохраним его

mov

cx,o

;Счетчик внутреннего цикла

de!2:

loop

de!2

;Внутренний цикл (64К шагов)

pop

CX

;Восстановим внешний счетчик

loop

dell

;Внешний цикл (2000 шагов)

pop

CX

восстановим СХ программы

ret

;Возврат в программу

Можно пойти еще дальше и составить подпрограмму таким образом, чтобы передаваемый в нее параметр характеризовал время задержки в се­кундах. Если не связываться с использованием системного таймера в каче­стве инструмента для определения интервала времени, а по-прежнему ре­ализовывать задержку с помощью процессорного цикла, ее величина будет зависеть от скорости работы конкретного компьютера и должна быть подо­брана экспериментально. Приведенный ниже вариант подпрограммы пра­

уианды и алгоритмы

137

;Пример 3-86.Подпрограмма задержки с преобразованием

;параметра, передаваемого в регистре SI

delay proc ;Процедура-подпрограмма

push AX ;Сохраним все

push BX ;используемые

push CX ;в подпрограмме

push DX ; регистры

mov AX,SI ;Первый сомножитель в АХ

mov BX,600 ;Второй экспериментально ;подобранный сомножитель

mul BX ;Произведение в DX:AX

mov СХ,АХ ;Нам оно нужно в СХ

dell: push CX ;Сохраним его

mov CX,0 ;Счетчик внутреннего цикла

de!2: loop de!2 ;Внутренний цикл (64К шагов)

pop CX восстановим внешний счетчик

loop dell ;Внешний цикл (2000 шагов)

pop DX ;Восстановим

pop CX ;все сохраненные

pop BX ;в начале подпрограммы

pop AX ;регистры

ret ;Возврат в программу

Эксперименты показали, что для получения правильной задержки значение параметра, обозначающее число секунд, следует умножать на 600. Поскольку при умножении в системе команд МП 86 первый сомно­житель должен находиться в регистре АХ, а второй не может быть непос­редственным значением и тоже, следовательно, должен быть помещен в один из регистров, и, к тому же, произведение занимает два регистра DX:AX, приходится сохранять при входе в подпрограмм)' не один регистр, как в предыдущем примере, а 4. Передаваемый в SI параметр переносится в АХ, в ВХ загружается второй сомножитель, а из полученного с помо­щью команды mul произведения используется младшая часть, находяща­яся в АХ. Таким образом, для данного варианта подпрограммы значение задержки не должно превышать 109 с (109 х 600 = 65500, что почти совпа­дает с максимально возможным значением 65535).

Следует обратить внимание на опасность, подстерегающую нас при выполнении операции умножения. Пусть значение передаваемого пара­метра состаштяет всего 5. При умножении на 600 получится число 3000, которое безусловно помещается в регистре АХ. Однако операция умноже­ния 16-разрядных операндов

mul BX

всегда, независимо от конкретной величины произведения, помещает его в пару регистров DX:AX, и, следовательно, при небольшой величине Произведения регистр DX будет обнуляться. Поэтому, хотя мы и не ис-

138