В предыдущих примерах рассматривалась программа на языке ассемблера, используемая совместно с интерпретатором Бейсика. Версия языка Бейсик, входящая в поставку IBM PC, является интерпретируемым языком. Это означает, что программа хранится в ЭВМ в виде, очень похожем на исходный текст. Интерпретатор не преобразует операторы языка Бейсик в команды машинного языка. Интерпретатор Бейсика во время выполнения просматривает каждый оператор программы и делает все, что необходимо для выполнения этого оператора.
$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
10 FORMAT(1X,'THE TIME IS: ',I2,':',I2,':',I2,'.',I2)
END
Фиг. 10.11 Программа определения времени дня на Фортране
Microsoft (R) Macro Assembler Version 5.00 4/2/89 16:07:35
Фиг. 10.12 Подпрограмма для программы на ФОРТРАНе Page 1-1
PAGE ,132
TITLE Фиг. 10.12 Подпрограмма для программы на ФОРТРАНе
FRAME STRUC
0000 ???? SAVEBP DW ?
0002 ???????? SAVERET DD ?
0006 ???????? A DD ? ; Указатель на параметр
000A FRAME ENDS
0000 CODE SEGMENT 'CODE'
DGROUP GROUP DATA
ASSUME CS:CODE,DS:DGROUP,ES:DGROUP,SS:DGROUP
0000 TIMER PROC FAR
PUBLIC TIMER ; Указание программе LINK на расположение
; программы TIMER
0000 55 PUSH BP
0001 8B EC MOV BP,SP ; Загрузка адреса стека
0003 B4 00 MOV AH,0
0005 CD 1A INT 1Ah ; Вызов BIOS для получения даты и времени
0007 C4 5E 06 LES BX,[BP].A ; Загрузка адреса поля параметров
000A 26: 89 17 MOV ES:[BX],DX ; Сохранение младшей части времени
000D 26: 89 4F 02 MOV ES:[BX+2],CX ; Сохранение старшей части времени
0011 5D POP BP
0012 CA 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. Делается это для того, чтобы редактор связей мог найти подпрограмму и правильно связать ее с программой на Фортране. Для интерпретатора Бейсика такой необходимости не было, поскольку программа на Бейсике не редактировалась совместно с программой на языке ассемблера.