На главную Назад
Добро пожаловать, уважаемый посетитель!

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

на языке ассемблера, хранящаяся в собственном объектном файле и

загружаемая в память интерпретатором Бейсика. А как в случае очень

маленькой программы. Представляется, что для такой программы

тратилось бы слишком много усилий на одну только загрузку ее из

собственного файйла. В приложении C справочника по языку Бейсик

приведен способ "упаковки" программы на машинном языке в область

памяти за пределами рабочей области интерпретатора. Приведем пример

применения другого способа.

 

На Фиг. 10.8 показана программа, написанная на языке

ассемблера, которой мы воспользуемся. Эта программа обращается к

BIOS для сдвига изображения на экране. Рассмотрев параметры,

хранящиеся в регистрах CX и DX, можно увидеть, что сдвигаемое окно

отображает лишь часть экрана. Мы будем исползовать приведенную

программу для разбиения экрана на несколько окон, в каждом из

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

реализации этого в языке Бейсик отсутствуют, понадобится процедура

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

 

Microsoft (R) Macro Assembler Version 5.001/1/80 04:07:03

Фиг. 10.8 Программа прокрутки окон на дисплееPage1-1

 

 

PAGE ,132

TITLE Фиг. 10.8 Программа прокрутки окон на дисплее

0000 CODE SEGMENT

ASSUMECS:CODE

0000 SCROLLPROC FAR

000055 PUSH BP

00018B EC MOV BP, SP

00038B 76 06 MOV SI, [BP+6] ; Загрузка адреса параметра

00068B 0C MOV CX, [SI] ; Загрузка параметра

00080A C0 OR AL, AL

000AB7 07 MOV BH, 7

000CB8 0601 MOV AX, 601h

000F75 0C JNZ WINDOW1 ; Определение требуемого окна

0011B9 0200 MOV CX, 200h ; Окно 1

0014BA 1010 MOV DX, 1010h

0017 DO_SCROLL:

0017CD 10 INT 10h

00195D POP BP

001ACA 0002 RET 2

001D WINDOW1:

001DB9 0514 MOV CX, 514h ; Окно 2

0020BA 1224 MOV DX, 1224h

0023EB F2 JMP DO_SCROLL

0025 SCROLLENDP

0025 CODE ENDS

END

 

Фиг. 10.8 Процедура сдвига изображения для Бэйсика

 

Как можно увидеть на листинге ассемблирования на Фиг. 10.8, для

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

используется входной параметр. Программа, написанная на языке

Бейсик, передает этот параметр в ассемблерную подпрограмму

оператором CALL. На Фиг.10.9(а) показано содержимое стека в момент

вызова в Бэйсике процедуры SCROLL. Оператор CALL помещает в стек

адрес параметра перед выполнением дальнего вызова (FAR CALL)

подпрограммы на машинном языке. Адрес в стеке является смещением

параметра относительно регистра DS. Первые команды процедуры SCROLL

извлекают этот адрес из регистра SI для того, чтобы загрузить

истинное значение в регистр CX. На Фиг.10.9(b) показано содержимое

стека после того, как процедура SCROLL поместила содержимое

регистра BP в стек, а затем переслала содержимое регистра SP в

регистр BP. Обратите внимание, что параметр находится в шести

байтах от вершины стека. Если бы программа на языке Бейсик

передавала более одного параметра, перед вызовом они были бы

аналогичным образом помещены в стек. Забегая вперед, заметим, что

перед возвратом процедура, используя команду RET 2, извлекает

параметры из стека. Интерпретатор Бейсика предполагает, что перед

возвратом подпрограмма удаляет параметры из стека.

 

ГДДДДДДДДДДДДґГДДДДДДДДДДДДґ

SPДДДДД>і Смещениеі SPДДДД>і Старое зна-і

і возвратаіі чение BPі<ДДДДBP

ГДДДДДДДДДДДДґГДДДДДДДДДДДДґ

і Сегментіі Смещениеі [BP+2]

і возвратаіі возвратаі

ГДДДДДДДДДДДДґГДДДДДДДДДДДДґ

і Смещениеіі Сегменті [BP+4]

і аргументаіі возвратаі

ГДДДДДДДДДДДДґГДДДДДДДДДДДДґ

і Смещениеі [BP+6]

і аргументаі

ГДДДДДДДДДДДДґ

 

(a)(b)

Фиг. 10.9 Стек при вызове процедуры

 

Подпрограмма SCROLL в зависимости от значения параметра

обрабатывает одно из двух окон экрана.Если параметр равен нулю,

то изображение в окне, заданном координатами (2, 0) и (16, 16)

сдвигается вверх на одну строку.Если параметр не равен нулю, то

на одну строку вверх сдвигается изображение в окне (5, 20), (18,

36).Перемещается текст только в заданном окне, остальной текст

или данные на экране остаются неподвижными.Реализация такого

оконного режима входит в функцию сдвига BIOS.Для ее использования

требуется лишь вызвать BIOS с правильно заданными параметрами.

 

На Фиг.10.10 представлена программа на языке Бейсик,

обращающаяся к процедуре SCROLL.В этом простом примере в каждое

окно записывается строка символов, а затем вызывается процедура

сдвига текста вверх.Эта Бэйсик-программа не более чем

иллюстрирует использование сдвига окон.

 

Первое, на что следует обратить внимание, это - способ загрузки

программы на машинном языке в систему.Программа содержится в

символьной строке P$.Каждый символ в строке соответствует одному

байту объектного кода из Фиг.10.8.В программу на Бэйсике эта

программа вводится с клавиатуры по листингу ассемблирования.Это -

одна из причин, по которой применение рассмотренного способа

ограничено лишь короткими программами.При вводе программы таким

способом очень легко сделать ошибки.

A

1 CLS

5 DEFINT A-Z

10 P$=CHR$(&H55)+CHR$(&H8B)+CHR$(&HEC)+CHR$(&H8B)+CHR$(&H76)+CHR$(&H6)

20 P$=P$+CHR$(&H8B)+CHR$(&HC)+CHR$(&HA)+CHR$(&HC9)+CHR$(&HB7)+CHR$(&H7)

30 P$=P$+CHR$(&HB8)+CHR$(&H1)+CHR$(&H6)+CHR$(&H75)+CHR$(&HC)+CHR$(&HB9)

40 P$=P$+CHR$(&H0)+CHR$(&H2)+CHR$(&HBA)+CHR$(&H10)+CHR$(&H10)+CHR$(&HCD)

50 P$=P$+CHR$(&H10)+CHR$(&H5D)+CHR$(&HCA)+CHR$(&H2)

60 P$=P$+CHR$(&H0)+CHR$(&HB9)+CHR$(&H14)

70 P$=P$+CHR$(&H5)+CHR$(&HBA)+CHR$(&H24)+CHR$(&H12)+CHR$(&HEB)+CHR$(&HF2)

100 ENTRY!=(PEEK(VARPTR(P$)+1))+(PEEK(VARPTR(P$)+2))*256

110 IF ENTRY!>32768! THEN ENTRY%=ENTRY!-65536! ELSE ENTRY%=ENTRY!

120 A$="АБВГДЕЖЗИК"

130 L=0:R=1

140 LOCATE 1,1:PRINT "Пример сдвига окна . . .э

200 LOCATE 15,1:PRINT A$;

210 CALL ENTRY%(L)

220 LOCATE 18,21:PRINT A$;

230 CALL ENTRY%(R)

240 A$=RIGHT$(A$,9)+LEFT$(A$,1)

250 GOTO 200

Фиг. 10.10 Бэйсик-программа для сдвига окон

 

Поскольку программа на машинном языке задана в строке P$, то

для определения адреса этой строки программа на языке Бейсик

использует функцию VARPTR.Для оператора CALL необходим адрес

подпрограммы, поэтому для его нахождения и используется функция

VARPTR.Воспользовавшись информацией из приложения C справочника

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

дескриптора строки.Возвращаемое функцей VARPTR значение является

адресом дескриптора строки для P$.Программа извлекает адрес

строки из дескриптора и присваивает его значение переменной ENTRY!.

Поскольку это значение может находиться в диапазоне от 0 до 65536,

подпрограмма должна преобразовать его в целое значение длиной в

одно слово, со значением от от -32768 до 32767.Это слово

помещается в переменную ENTRY%.В остальных строках программы в

сдвигаемые окна записывается символьная строка, а затем для

перемещения текста вызывается подпрограмма SCROLL.

 

При запуске этой программы вы увидите, что данные в двух окнах

перемещаются независимо.Такой прием позволяет задать два

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

от друга.Если написать немного более длинную программу, можно

было бы ограничить каждое окно рамкой, чтобы деиствительно отделить

их друг от друга.Применение подобных методов построения окон

позволяет писать довольно симпатичные программы с одновременным

выводом на экран наскольких фрагментов текста.

 

Прежде чем покончить с этой программой, давайте просмотрим

через отладчик часть программы, написанную на машинном языке.Для

этого надо иметь готовую к выполнению программу ДОС DEBUG.Это

достигается следующим образом:сначала загружается программа

DEBUG, а затем загружается BASIC.COM (или BASICA.COM, если

используется расширенный Бейсик).После загрузки программы Бейсик

замените первый символ в P$ (и соответственно, первый байт

программы на машинном языке), на CHR$($HCC).Это - код для

прерывания INT 3 прерывания по точке прерывания.Теперь, когда во

время выполнения программы на языке Бейсик она вызывает

подпрограмму на машинном языке, управление получает программа

DEBUG.Теперь можно вновь заменить код 0CCH на исходное значение

(в данном случае 055H).Программу DEBUG можно использовать для

трассировки программы на машинном языке.Конечно, если программа

на языке ассемблера хорошо написана и коротка, то такая отладка не

так необходима.На самом же деле вы, вероятно, заметите, что в

большинстве случаев из-за ошибок при вводе с клавиатуры программы

на машинном языке в строку интерпретатора Бейсик возникает

множество проблем.


 

Mail.ru