Компилируемые языки высокого уровня

      В предыдущих примерах рассматривалась программа на языке

    ассемблера, используемая совместно с интерпретатором Бейсика.

    Версия языка Бейсик, входящая в поставку 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

      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.  Делается это для того, чтобы редактор связей мог найти

    подпрограмму и правильно связать ее с программой на Фортране.  Для

    интерпретатора Бейсика такой необходимости не было, поскольку

    программа на Бейсике не редактировалась совместно с программой на

    языке ассемблера.

Hosted by uCoz