|
При первом способе подпрограмма на
машинном языке добавляется к
программе для интерпретатора Бэйсика.
Пожалуй, использование
интерпретатора Бейсика является наиболее
распространенным методом
написания программ для персональной ЭВМ.
Подпрограмма на языке
ассемблера, которую предполагается
включить в разрабатываемую
программу, довольно велика - более 100
байт. Ассемблерную процедуру
такой длины трудно вставить в текст
программы на языке Бейсик,
способ, позволяющий сделать это будет
рассмотрен в следующем
примере.
Функция, которую мы добавляем к программе
на языке Бейсик
позволяет выводить на принтер графические
изображения. IBM PC
снабжена графическими средствами.
Графические команды позволяют
программно управлять отдельными точками,
выводимыми на принтер, во
многом подобно тому, как в графическом
режиме адаптер цветного
дисплея дает программисту возможность
управлять отдельными точками
растра. На Фиг. 10.4 представлены
графические команды, которые
потребуются в рассматриваемом примере.
Практически, графические
функции реализуются на принтере через
управляющие последователь-
ности символов. Вместо символа в коде
ASCII программа выдает на
принтер служебный символ (27 в коде
ASCII). Следующие за ним
символы задают уже не символы для вывода
на печать, а определенные
действия принтера. Как видно из Фиг. 10.4,
существуют команды для
вывода на принтер изображения точки, в
результате выполнения
которых печатается определенная точка
изображения.
Команда Действие
---------------------------------------------------------
ESC + "3" + nУстановка промежутка между
строками n/216
Esc + "K" +n1+n2+v1...vkПечатать образы точек v1...vk
(k = n1 + 256*n2)как 480 точек поперек страницы
---------------------------------------------------------
Фиг.10.4 Графические команды для принтера
Приведенная на Фиг. 10.5 программа
использует указанные команды
для вывода на принтер образа экрана
графического дисплея размером
320*200 точек. Каждая точка растра
передается на принтер. Если
точка на экране имеет цвет фона, то
соответствующая точка на печать
не выдается. Если точка окрашена в один из
трех основных цветов, то
программа выводит на печать черную точку.
Эта программа не
масштабирует изображение, поэтому
окружность на экране может
отобразиться в эллипс на принтере. Между
тремя основными цветами не
проводится различий. Цветное изображение
превращается в
черно-белое.
Подпрограмма PRINT_SCREEN является
процедурой типа FAR. Вызов
ее из языка Бейсик является вызовом типа
FAR, поэтому и возврат в
программу должен быть соответствующего
типа. Последовательность ESC
+ "3" + 24 устанавливает такой
интервал между строками печати, что
один ряд точек вплотную примыкает к
другому. В печатающей головке
имеется восемь иголок, расстояние между
которыми равно 1/72 дюйма.
Если сделать интервал между строками
равным 8/72 дюйма (или 24/216
дюйма), то ряды точек соединятся.
Приведенный фрагмент программы
показывает способ пересылки на устройство
печати последовательности
служебных символов. Управляющая
последовательность символов и чисел
пересылается на принтер как обычные
символы. Остальное обеспечивает
устройство печати.
При каждом проходе печатающей головки на
бумаге остается по
восемь рядов точек (по одному на каждую
иголку печатающей головки)
вкаждой из 320 колонок. От метки NEXT_ROW в
программе
последовательность ESC + "K" +
64 + 1 пересылается на принтер. Это
означает, что последующие 320 байт (64 +
1*256) являются образами
точек для получения графического
изображения на принтере. В
графическом режиме "K" на
принтере можно получить изображение
шириной до 480 точек.
Для считывания точек с дисплея программа
использует видео
функцию BIOS . Эта функция считывает
восемь рядов точек текущнго
столбца и собирает их в один байт:
"1" означает, что точка имеет
основной цвет и должна появиться на
бумаге. Цикл продолжается через
метку NEXT_COLUMN - до тех пор, пока все
320 столбцов (что
соответствует 320 байтам) не будут
переданы на принтер . После
перехода принтера на новую строку при
помощи служебных символов
"возврат каретки" и
"перевод строки" (13 и 10 в коде ASCII),
программа пересылает следующую группу из
восьми рядов. За 25
проходов печатающей головки выводятся все
200 рядов. Возврат в
интерпретатор Бейсика производится при
помощи возврата типа FAR.
В рассматриваемой программе было бы удобно
использовать
процедуру PRINT. Эта процедура выдает один
байт на принтер при
помощи функции печати BIOS. Функция
помещает необходиые для базовой
системы ввода-вывода установки регистров в
определенное место. Если
не использовать указанную функцию, то
программа сама должна была бы
устанавливать регистры AH и DX равными
нулю перед каждым вызовом
процедуры PRINT.
A
Microsoft (R) Macro Assembler Version 5.00 1/1/80 04:06:57
Фиг. 10.5 Печать графической копии дисплеяPage1-1
PAGE
,132
TITLE
Фиг. 10.5 Печать графической копии дисплея
= 001B ESC EQU 27 ; Символ Escape
0000 CODE SEGMENT
ASSUMECS:CODE
0000
PRINT_SCREEN PROC FAR
0000B0 1B MOV AL, ESC ; Установка
перевода строки на 1/8 дюйма
0002E8 0060 R CALL PRINT
0005B0 33
MOV AL, '3'
0007E8 0060 R CALL PRINT
000AB0 18 MOV AL, 24 ; 1/8 = 24/216 дюйма
000CE8 0060 R CALL PRINT
000FBA 0000 MOV DX, 0 ; Номер строки
0012
NEXT_ROW:
0012B0 1B MOV AL, ESC
0014E8 0060 R CALL PRINT
0017B0 4B MOV AL, 'K'
0019E8 0060 R CALL PRINT
001CB0 40 MOV AL, 320-256
001EE8 0060 R CALL PRINT
0021B0 01 MOV AL, 1
0023E8 0060 R CALL PRINT
0026B9 0000 MOV CX, 0 ; Номер столбца
0029
NEXT_COLUMN:
002952 PUSH DX ; Сохранение номера строки
002ABB 0008 MOV BX, 8 ; Число одновлеменно обрабатываемых
точек
002D
NEXT_DOT:
002DD0 E7 SHL BH, 1 ;
Освобождение младшего разряда
002FB4 0D MOV AH, 13 ; Чтение цвета точки из памяти дисплея
0031CD 10 INT 10h
00330A C0 OR AL, AL
003574 03 JZ BACKGROUND ; Проверка на
цвет фона
003780 CF 01 OR BH, 1 ; Не фон,
необходимо вывести точку на печать
003A
BACKGROUND:
003A42 INC DX ; Переключение на следующую строку
003BFE CB DEC BL ; Уменьшение
счетчика строк в данном проходе
003D75 EE JNZ NEXT_DOT
003F8A C7 MOV AL, BH ; Печать 8-ми точек
0041E8 0060 R CALL PRINT ; Вывод на
печать
00445A POP DX ; Восстановление номера строки начала
прохода
004541 INC CX ; Переключение на следуюий столбец
004681 F9 0140 CMP CX, 320 ; Все столбцы
выведены?
004A75 DD JNZ NEXT_COLUMN
004CB0 0D MOV AL, 13 ; Переход на следующую строку на принтере
004EE8 0060 R CALL PRINT
0051B0 0A MOV AL, 10
0053E8 0060 R CALL PRINT
005683 C2 08 ADD DX, 8 ;
Переключение на слдующую группу из 8 строк
005981 FA 00C8 CMP DX, 200 ; Все строки
выведены?
005D72 B3 JB NEXT_ROW
005FCB RET
; Возврат в BASIC
Фиг. 10.5Печать
графического экрана (начало)
0060
PRINT_SCREEN ENDP
0060 PRINT PROC
NEAR
006052 PUSH DX
0061B4 00 MOV AH, 0 ; Печать
символа, находящегося в регистре AL
0063BA 0000 MOV DX, 0
0066CD 17 INT 17h
00685A POP DX
0069C3 RET
006A PRINT ENDP
006A CODE ENDS
ENDA
Фиг. 10.5Печать графического экрана (продолжение)
Как же обратиться к этой процедуре из
программы, написанной на
языке Бейсик? В языке Бейсик существуют
два способа подключения
подпрограмм. Во время работы интерпретатор
Бейсика использует
оставшуюся память системы (до 64 кбайт) в
качестве рабочей области.
Если в системе более 96 кбайт памяти,
часть памяти будет не
доступна для интерпретатора Бейсика. Лучше
всего поместить нашу
процедуру в эту область. Если свободной
области памяти нет, то
можно специально выделить некоторый объем
памяти из рабочей области
интерпретатора Бейсика для хранения
подпрограммы. В данном примере
подпрограмма будет храниться вне рабочей
области интерпретатора
Бейсика. В следующем примере будет
показано, как включить процедуру
в контролируемую интерпретатором Бейсика
область памяти.
На Фиг. 10.6 показана последовательность
действий для
подготовки подпрограммы к дальнейшему
использованию.
Соответствующая информация приведена в
приложении C справочника по
языку Бейсик. Программа (на Фиг. 10.6) предназначена для машины с
оперативной памятью 96 кбайт и более.
Программа ассемблируется
обычным образом. При редактировании связей
задается опция /H.
Редактор связей создает файл типа .EXE
таким образом, что программа
загружается в верхние адреса оперативной
памяти, а не с самого
низкого из доступных адресов.
Чтобы подключить процедуру к программе,
написанной на языке
Бейсик, нам потребуется программа DEBUG.
После загрузки программы
на языке Бейсик во время работы программы
DEBUG и уточнения
значений регистров, загружаем процедуру на
языке ассемблера.
Приведенный пример реализован на машине с
памятью 128 кбайт.
Значение регистра CS, равное 1FF9H,
указывает на то, что программа
помещена в 70H байт от конца оперативной
памяти. Заметим, что
рассматриваемая программа имеет объем
около 6AH байт, так что
редактор связей разместил программу с
самого старшего адреса
памяти, допускающего выравнивание по границе
параграфа. Следует
также заметить, что эта программа является
сегментно -
перемещаемой. Это означает, что ее можно
перемещать в памяти,
поскольку первая ее команда имеет смещение
0 относительно текущего
сегмента кода. При переносе этой программы
на машину с большим или
меньшим объемом памяти эта особенность
оказывается решающей.
A
B>A:MASM FIG10-5,,,;
The IBM Persona Computer MACRO Assembler
Version 1.00 (C)Copyright IBM Corp 1981
Warning Severe
ErrorsErrors
00
B>A:LINK FIG10-5,,,/H;
IBM Personal Computer Linker
Version 1.10 (C)Copyright IBM Corp 1982
Warning: No STACK segment
There was 1 error detected
B>A:DEBUG A:BASIC.COM
-R
AX=0000 BX=0000 CX=2B80 DX=0000 SP=FFF0
BP=0000 SI=0000 DI=0000
DS=04B5 ES=04B5 SS=04B5 CS=04B5 IP=0100 NV
UP DI PL NZ NA PO NC
04B5:0100 E91329JMP2A16
-NFIG10-5.EXE
-L
-R
AX=0000 BX=0000 CX=006A DX=0000 SP=0000
BP=0000 SI=0000 DI=0000
DS=04B5 ES=04B5 SS=1FF9 CS=1FF9 IP=0000 NV
UP DI PL NZ NA PO NC
1FF9:0000 B01BMOVAL,1B
-RSS
SS 1FF9
:4B5
-RCS
CS 1FF9
:4B5
-RIP
IP 0000
:100
-G
---- В интерпретаторе Бэйсика введите
команды
DEF SEG = &H1FF9
BSAVE "FIG10-5",0,&H70
Фиг. 10.6 (а) Создание подпрограммы для Бэйсика
B>A:MASM FIG10-5,,,;
The IBM Persona Computer MACRO Assembler
Version 1.00 (C)Copyright IBM Corp 1981
Warning Severe
ErrorsErrors
00
B>A:LINK FIG10-5,,,/H;
IBM Personal Computer Linker
Version 1.10 (C)Copyright IBM Corp 1982
Warning: No STACK segment
There was 1 error detected
B>A:DEBUG A:BASIC.COM /M:&H8000
-R
AX=0000 BX=0000 CX=2B80 DX=0000 SP=FFF0
BP=0000 SI=0000 DI=0000
DS=04B5 ES=04B5 SS=04B5 CS=04B5 IP=0100 NV
UP DI PL NZ NA PO NC
04B5:0100 E91329JMP2A16
-NFIG10-5.EXE
-L
-R
AX=0000 BX=0000 CX=006A DX=0000 SP=0000
BP=0000 SI=0000 DI=0000
DS=04B5 ES=04B5 SS=0FF9 CS=0FF9 IP=0000 NV
UP DI PL NZ NA PO NC
0FF9:0000 B01BMOVAL,1B
-RSS
SS 0FF9
:4B5
-RCS
CS 1FF9
:4B5
-RIP
IP 0000
:100
-G
---- В интерпретаторе Бэйсика; введите
команды
DEF SEG = &H0FF9
BSAVE "FIG10-5",0,&H70
(b)
A
Фиг. 10.6 (а) Создание подпрограммы для
Бэйсика; (b) Создание
подпрограммы для Бэйсика на машине с 64K
Теперь мы имеем дело с интерпретатором
Бейсика. Нам необходимо
восстановить содержимое регистров таким,
каким оно было после
загрузки Бейсика. После того, как
интерпретатор Бейсика запущен,
для локализации подпрограммы используется
команда DEF SEG. Команда
BSAVE помещает обратно на дискету
объектный код, готовый к новой
загрузке из Бейсика при помощи команды
BLOAD.
В части (b) Фиг. 10.6, повторяются
действия из части (а), но
для машины с объемом памяти 64 кбайт.
Различие здесь состоит в том,
что интерпретатор Бейсика не может
использовать всю память под
рабочую область. Опция /M в командной
строке Бейсика ограничивает
рабочую область Бейсика и оставляет место
для подпрограммы.
Аналогичная команда потребуется и при
запуске программы.
Программой DEBUG можно воспользоваться для
вашей ассемблерной
процедуры и при работе интерпретатора
Бейсика .Включите в команду
G при запуске программы Бейсика установку
контрольной точки в
подпрограмме.По достижении контрольной точки работа
интерпретатора Бейсика приостанавливается,
и производится обычная
для программы DEBUG выдача содержимого
регистров.
Теперь все готово для выполнения
подпрограммы на языке
ассемблера как части программы на языке
Бейсик. Снова предположим,
что система располагает 128 кбайтами
памяти, и выполним следующую
последовательность действий:
введите "BASIC" на уровне команд
DOS;
введите "SCREEN1" во время
работы интерпретатора Бейсика.
Фиг. 10.7 Печатная копия экрана
Эти действия вводят нас в интерпретатор и
переводят режим
изображения на размер 320*200 точек. На
Фиг. 10.7. показаны
оставшиеся события этой истории. Команда
BLOAD загружает процедуру
в ту же область памяти, из которой она
была сохранена. При желании
в команде BLOAD можно задать параметры,
обеспечивающие загрузку
программы в другую область памяти.
Оператор LINE дает процедуре
графической распечатки экрана информацию
для печати. Для вызова
этой процедуры мы используем команду DEF
SEG, чтобы установить
значение регистра CS на процедуру.
Значение регистра IP для
процедуры помещается в простую переменную.
Оператор CALL
осуществляет дальний вызов по заданному
адресу. Фиг. 10.7
представляет собой копию реальной
распечатки, полученной при
выполнении приведенной программы.
Если в системе 64Кбайт памяти, то
программа будет отлична в
двух аспектах. Для вызова интерпретатора
Бейсика используется
команда BASIC/M:&H8000, резервирующая
верхнюю часть памяти для
нашей ассемблерной процедуры, а команда
DEF SEG задает адрес
подпрограммы, как это было сделано в части
(b) Фиг. 10.6.
|