|
В предыдущих примерах рассматривалась
программа на языке
ассемблера, используемая совместно с
интерпретатором Бейсика.
Версия языка Бейсик, входящая в поставку
IBM PC, является
интерпретируемым языком.Это означает, что программа хранится в
ЭВМ в виде, очень похожем на исходный
текст.Интерпретатор не
преобразует операторы языка Бейсик в
команды машинного языка.
Интерпретатор Бейсика во время выполнения
просматривает каждый
оператор программы и делает все, что
необходимо для выполнения
этого оператора.
По-другому работает компилятор.Он преобразует операторы языка
высокого уровня в команды машинного языка.Фирма IBM предлагает
компиляторы для персональной ЭВМ с языков
Бейсик, Паскаль, Фортран
и Кобол.Выходом компилятора является программа на машинном языке
(файл *.OBJ), т.е.он во многом аналогичен выходу ассемблера.
Запуск программы, написанной на
компилируемом языке высокого уровня
состоит из двух этапов.Сначала программа должна быть
скомпилирована, и должны быть
отредактированы связи.Затем она
может быть выполнена.Интерпретируемая программа может выполняться
непосредственно, минуя этап компиляции.
Компилируемые языки на персональной ЭВМ
аналогичны языку Бейсик
в том смысле, что не дают возможности
делать с техническим
обеспечением все, что вздумается.На самом деле интерпретатор
Бейсика еще позволяет программисту при
помощи операторов программы
считывать и записывать информацию с портов
ввода-вывода и ячеек
памяти.Другие языки не всегда предоставляют даже эту возможность.
Поэтому применение подпрограмм на языке
ассемблера в программе на
Паскале или Фортране может оказаться даже
более необходимым.
Возможно, вам придется заняться этим, если
вы захотите
воспользоваться всеми возможностями
технического обеспечения.
К счастью, включить процедуру на языке
ассемблера в программу
на компилируемом языке высокого уровня
довольно просто, так как
выходом компилятора является объектный
файл, готовый к
редактированию связей.Выход ассемблера - тоже объектный файл.
Следовательно, достаточно лишь связать
программу на языке высокого
уровня и программу на языке ассемблера при
помощи редактора связей
DOS.Нет необходимости соединять программы в процессе выполнения,
как это делалось для интерпретатора
Бейсика.
Построим пример на языке Фортран (Фиг.10.11).Для языка
Паскаль все очень похоже.Подобный пример приведен в приложении D
справочника к компилятору Фортрана.В примере головная программа,
написанная на Фортране, объединена с
программой на языке
ассемблера, которая считывает текущее
время, используя программное
прерывание базовой системы ввода-вывода.Подпрограмма на языке
ассемблера обращается к BIOS для
определения текущего времени и
возвращает соответствующее значение в
программу на Фортране.
Головная программа преобразует кванты
таймера, в текущее время,
выраженное в часах, минутах и секундах.
На Фиг.10.11 представлена головная программа на Фортране.
Эта программа вызывает внешнюю процедуру
TIMER, имеющую один
параметр A - четырехбайтовое целое
значение.Возрващаемое
процедурой TIMER значение представляет собой текущее время,
выраженное в квантах таймера и
отсчитываемое от полуночи.
Программа на Фортране по полученному из
процедуры TIMER значению
вычисляет время в часах(HOURS),
минутах(MINS), секундах(SECS) и
сотых долях секунды(HSECS).Отметим, насколько проще реализовать
умножение и деление на языке Фортран, чем
на языке ассемблера.
Можно убедиться, что выполнение всех
подобных операций на Фортране
существенно упрощает
программирование.Чрезвычайно удобен и
способ
преобразования целых переменных в
выдаваемые на печать символы при
помощи операторов Фортрана WRITE и FORMAT.На языке ассемблера для
выполнения тех же самых действий
потребовалось бы несколько сот
строк.Вспомним пример для сопроцессора 8087, где программа
преобразовывала число с плавающей точкой в
код ASCII.В этой
программе содержалось значительное число
команд, и, кроме того,
использовался сопроцессор 8087.
$STORAGE=4
INTEGER A,HOURS,MINS,SECS,HSECS
CALL TIMER(A)
HOURS=A/65543
A=A-HOURS*65543
MINS=A/1092
A=A-MINS*1092
SECS=A/18
HSECS=(100*(A-SECS*18))/18
WRITE(*,10)HOURS,MINS,SECS,HSECS
10FORMAT(1X,'THE
TIME IS: ',I2,':',I2,':',I2,'.',I2)
END
Фиг. 10.11 Программа определения времени
дня на Фортране
Microsoft (R) Macro Assembler Version 5.004/2/89
16:07:35
Фиг. 10.12 Подпрограмма для программы на ФОРТРАНеPage1-1
PAGE
,132
TITLE
Фиг. 10.12 Подпрограмма для программы на ФОРТРАНе
FRAME
STRUC
0000???? SAVEBPDW ?
0002???????? SAVERET DD ?
0006???????? A
DD ?
; Указатель на параметр
000A FRAME ENDS
0000 CODE SEGMENT 'CODE'
DGROUPGROUP DATA
ASSUMECS:CODE,DS:DGROUP,ES:DGROUP,SS:DGROUP
0000 TIMER PROC
FAR
PUBLICTIMER ; Указание
программе LINK на расположение
;программы TIMER
000055 PUSH BP
00018B EC MOV BP,SP; Загрузка
адреса стека
0003B4 00 MOV AH,0
0005CD 1A INT 1Ah ; Вызов BIOS для
получения даты и времени
0007C4 5E 06 LES BX,[BP].A; Загрузка адреса
поля параметров
000A26: 89 17 MOV ES:[BX],DX; Сохранение младшей части времени
000D26: 89 4F 02 MOV ES:[BX+2],CX; Сохранение
старшей части времени
00115D POP BP
0012CA 0004 RET 4 ; Возврат с удалением параметров из
стека
0015 TIMER ENDP
0015 CODE ENDS
END
Фиг. 10.12 Ассемблерная процедура для
программы на Фортране
На Фиг.10.12 представлена подпрограмма на языке ассемблера -
процедура TIMER.В этой несложной программе для считывания
текущего времени и сохранения полученного
значения в двойном слове
используется обращение к BIOS.Здесь нам необходимо рассмотреть
способ передачи параметров из программы на
Фортране в подпрограмму
на языке ассемблера.
На Фиг.10.13 показано содержимое стека в
начальный момент
выполнения подпрограммы на языке
ассемблера.Точно так же, как
интерпретатор Бейсика, программа на
Фортране помещает адрес
параметра в стек.Однако компиляторы Фортрана и Паскаля
передают
указатель длиной в два слова, а не одно
только смещение параметра.
Это означает, что программа на языке
ассемблера, прежде чем
получить доступ к параметру, должна
установить как сегментный
регистр, так и адрес смещения.Если бы параметров было более
одного, то программа на Фортране перед
вызовом поместила бы в стек
значения адресов и остальных параметров.
ГДДДДДДДДДДДДґ
SPДДДД>і Смещениеі
і возвратаі
ГДДДДДДДДДДДДґ
і Сегменті
і возвратаі
ГДДДДДДДДДДДДґ
і Смещениеі
і аргументаі
ГДДДДДДДДДДДДґ
і Сегменті
і аргументаі
ГДДДДДДДДДДДДґ
Фиг. 10.13 Стек для вызова процедуры в
Фортране
Подпрограмма TIMER на Фиг.10.12 адресует стек, помещая в него
регистр BP и устанавливая его на вершину
стека.Структура FRAME
помогает идентифицировать разные значения
в стеке после того как
программа сохранит в нем значение BP.Команда LES BX,[BP]+A
помещает адрес параметра в пару регистров
ES:BX.Используя этот
адрес, программа помещает четырехбайтовое
значение текущего времени
в четырехбайтовую целую переменную.
Заметим, что процедура TIMER извлекает
адрес параметра из стека
при выполнении команды возврата точно так
же, как это делалось в
программах на языке Бейсик.Заметим также, что в этой ассемблерной
программе для идентификации имени TIMER
используется оператор
PUBLIC.Делается это для того, чтобы редактор связей мог найти
подпрограмму и правильно связать ее с
программой на Фортране.Для
интерпретатора Бейсика такой необходимости
не было, поскольку
программа на Бейсике не редактировалась
совместно с программой на
языке ассемблера.
|