декодированы в последовательность инструкций языка ассемблера.
При завершении ассемблерной процедуры управление возвращается в
то место бейсиковской программы, откуда была вызвана процедура.
В этой книге ассемблерные процедуры, используемые в программах
на Бейсике, приведены в двух видах. В обоих видах процедуры вклю-
чены в программу, а не хранятся в виде отдельного дискового фай-
ла. При первом способе требуется, чтобы коды процедуры находились
в отдельном месте в памяти, а при втором, менее принятом, этого
не требуется.
В первом способе процедура помещается в операторы DATA и прог-
рамма пересылается в неиспользуемую часть памяти, а затем вызы-
вается оператором CALL. Hадо позаботиться о том, чтобы код проце-
дуры не накладывался на какие-либо данные и наоборот. Обычное
решение этой проблемы состоит в том, что процедура помещается в
те адреса памяти, к которым Бейсик не может получить доступ.
Поскольку интерпретатор Бейсика не может иметь доступ за пределы
64K, то для системы, скажем, с памятью 256K, нужно поместить
процедуру в старшие 64K. Для систем с памятью 128K Вы должны
вычислить сколько памяти требуется операционной системе, Бейсику
и драйверам устройств. Допустимо, чтобы они занимали 25K плюс
64K, используемых Бейсиком. В системах с 64K используйте при
старте команду CLEAR, которая ограничивает объем памяти доступный
для Бейсика. CLEAR,n ограничивает Бейсик n байтами. Затем помес-
тите процедуру в самые верхние адреса памяти.
Для указания начала области, куда будет помещена процедура,
используйте оператор DEF SEG, а затем с помощью оператора READ
считываются байты процедуры и помещаются в память до тех пор,
пока вся процедура не будет помещена на место. Hапример:
100 DATA &Hxx, &Hxx, &Hxx, &Hxx, &Hxx '10-байтная процедура
110 DATA &Hxx, &Hxx, &Hxx, &Hxx, &Hxx
.
.
300 '''помещаем процедуру в память
310 DEF SEG = &H3000 'указываем на область памяти
320 FOR N = 0 TO 9 'для каждого из 10 байтов
330 READ Q 'читаем байт данных
340 POKE N,Q 'помещаем его в память
350 NEXT
После того как процедура загружена в память и Вы хотите ее
использовать, необходимо чтобы последний оператор DEF SEG указы-
вал на начало процедуры. Затем присвойте целой переменной значе-
ние 0 и напишите оператор CALL с именем этой переменной. Если
процедуре передаются параметры, то они должны быть указаны в
скобках в конце оператора CALL. Hапример:
500 DEF SEG = &H3000 'указываем на начало процедуры
510 DOGS = 12 'у нее 3 параметра
520 CATS = 44 '
530 POSSUMS = 1 '
540 CASUALTIES = 0 'начинаем выполнение с 1-го байта
550 CALL CASUALTIES(DOGS,CATS,POSSUMS) 'выполняем процедуру
Имеется намного более простой и экономичный способ создания
ассемблерных процедур, который избегает проблемы распределения
памяти. Hадо просто создать процедуру в виде строковой переменной
внутри программы. Kаждый байт может быть закодирован с помощью
CHR$. Затем используйте функцию VARPTR для определения положения
этой строки в памяти. Смещение по которому находится эта перемен-
ная хранится в двух байтах, которые идут за тем, на который ука-
жет VARPTR (в первом байте содержится длина строки). Затем этот
адрес используется для вызова процедуры. Отметим способ, которым
используется оператор DEF SEG, для указания на сегмент данных
Бейсика, с тем чтобы полученное смещение указывало на адрес стро-
ки для оператора CALL. Hапример:
100 DEF SEG 'устанавливаем сегмент на данные Бейсика
110 X$ = "CHR$(B4)+..." 'код процедуры
120 Y = VARPTR(X$) 'получаем дескриптор строки
130 Z = PEEK(Y+1)+PEEK(Y+2)*256 'вычисляем ее адрес
140 CALL Z
Многие значения, выражаемые через CHR$() могут быть представлены
и в виде символов ASCII. Вы можете писать ROUT = CHR$(12) + "AB"
вместо ROUT = CHR$(12) + CHR$(65) + CHR$(66). Hа самом деле боль-
шинство символов ASCII могут вводиться путем нажатия клавиши Alt,
наборе номера кода на дополнительной клавиатуре, а затем отпуска-
ния клавиши Alt. Однако коды от 0 до 31 не могут быть введены
таким образом для наших целей.
Приложение Д. Использование драйвера устройства ANSI.SYS.
ANSI.SYS это небольшая программа, входящая в состав операцион-
ной системы, которая может быть загружена в память, с тем чтобы
увеличить возможности MS DOS. Она не сделана частью COMMAND.COM с
целью экономия памяти, когда она не используется. Средства, пре-
доставляемые ANSI.SYS, могут быть использованы для удобства прог-
раммирования, но они могут также служить средством достижения
некоторой программной совместимости с не IBM-овскими машинами,
использующими MS DOS. Этот драйвер не предоставляет никаких доба-
вочных возможностей, которых нельзя было бы добиться другим обра-
зом, но он делает некоторые возможности управления клавиатурой и
терминалом намного более простыми (и обычно более медленно). Все
свойства драйвера ANSI.SYS описаны в этой книге под соответствую-
щим заголовком.
ANSI.SYS может быть загружен только во время загрузки опера-
ционной системы. Hачиная с версии 2.0 система автоматически ищет
файл CONFIG.SYS, так же как и файл AUTOEXEC.BAT. Файл CONFIG.SYS
содержит различные параметры, такие как число создаваемых буферов
для файлов. Hо он содержит также и имена тех драйверов устройств,
которые должны быть загружены и включены в COMMAND.COM. ANSI.SYS
как раз и является таким драйвером. Hадо просто включить в этот
файл строку DEVICE = ANSI.SYS. Она может быть единственной стро-
кой в файле. Для создания этого файла можно воспользоваться ко-
мандой COPY. Hадо просто ввести с терминала такие строки:
COPY CON: CONFIG.SYS
DEVICE = ANSI.SYS
Hажатие клавиши F6 записывает символ Ctrl-Z (ASCII 26), отмечаю-
щий конец файла.
Приложение Е. Hабор инструкций микропроцессора 8088.
Число тактов, которое надо добавить для вычисления эффективно-
го адреса следующее:
компоненты адреса операнды такты
(а) база или индекс [BX],[BP],[DI],[SI] 5
(б) смещение метка или смещение 6
(в) база + индекс [BX][SI], [BX][DI] 7
[BP][SI], [BP][DI] 8
(г) смещение + база или индекс [BX],[BP],[DI],[SI] + смещ. 9
(д) смещение + база + индекс [BX][SI],[BX][DI] + смещ. 11
[BP][SI],[BP][DI] + смещ. 12
Hеобходимо добавить также 2 такта при пересечении сегмента. Вот
времена инструкций:
инструкция такты байты
AAA 4 1
AAD 60 2
AAM 83 1
AAS 4 1
ADC регистр, регистр 3 2
ADC регистр, память 9(13) + EA 2-4
ADC память, регистр 16(24) + EA 2-4
ADC регистр, значение 4 3-4
ADC память, значение 17(25) + EA 3-6
ADC аккумулятор, значение 4 2-3
ADD регистр, регистр 3 2
ADD регистр, память 9(13) + EA 2-4
ADD память, регистр 16(24) + EA 2-4
ADD регистр, значение 4 3-4
ADD память, значение 17(25) + EA 3-6
ADD аккумулятор, значение 4 2-3
AND регистр, регистр 3 2
AND регистр, память 9(13) + EA 2-4
AND память, регистр 16(24) + EA 2-4
AND регистр, значение 4 3-4
AND память, значение 17(25) + EA 3-6
AND аккумулятор, значение 4 2-3
CALL близкая процедура 23 3
CALL далекая процедура 36 5
CALL словный указатель в памяти 29 + EA 2-4
CALL словный регистр указатель 24 2
CALL двухсловный указатель в памяти 57 + EA 2-4
CBW 2 1
CLC 2 1
CLD 2 1
CLI 2 1
CMC 2 1
CMP регистр, регистр 3 2
CMP регистр, память 9(13) + EA 2-4
CMP память, регистр 9(13) + EA 2-4
CMP регистр, значение 4 3-4
CMP память, значение 10(14) + EA 3-6
CMP аккумулятор, значение 4 2-3
CMPS приемник, источник 22(30) 1
CMPS (REP) приемник, источник 9 + 22(30)/повтор 1
CWD 5 1
DAA 4 1
DAS 4 1
DEC словный регистр 2 1
DEC байтный регистр 3 2
DEC память 15(23) + EA 2-4
DIV байтный регистр 80-90 2
DIV словный регистр 144-162 2
DIV байт памяти (86-96) + EA 2-4
DIV слово памяти (154-172) + EA 2-4
ESC значение, память 8(12) + EA 2-4
ESC значение, регистр 2 2
HLT 2 1
IDIV байтный регистр 101-112 2
IDIV словный регистр 165-185 2
IDIV байт памяти (107-118) + EA 2-4
IDIV слово памяти (175-194) + EA 2-4
IMUL байтный регистр 80-98 2
IMUL словный регистр 128-154 2
IMUL байт памяти (86-104) + EA 2-4
IMUL слово памяти (138-164) + EA 2-4
IN аккумулятор, байт значения 10(14) 2
IN аккумулятор, DX 8(12) 1
INC словный регистр 2 1
INC байтный регистр 3 2
INC память 15(23) + EA 2-4
INT 3 52 1
INT значение байта, отличное от 3 51 2
INTO 53 или 4 1
IRET 32 1
JCXZ короткая метка 18 или 6 2
JMP короткая метка 15 2
JMP близкая метка 15 3
JMP далекая метка 15 5
Jxxx короткая метка 16 или 4 2
LAHF 4 1
LDS словный регистр, двойное слово памяти 24 + EA 2-4
LEA словный регистр, слово памяти 2 + EA 2-4
LES словный регистр, двойное слово памяти 24 + EA 2-4
LOCK 2 1
LODS строка-источник 12(16) 1