рованием и т.д. BL содержит код, предполагающий действие для восстановления, такое как "пов- торить", "прекратить" или "запросить у пользователя". Наконец, CH возвращает число, определяющее место где возникли проблемы: на блочном устройстве, на символьном, в памяти? Данные для этих кодов ошибок весьма обширны. Полную информацию о них см. в Техническом руководстве по MS DOS 3.0. Поскольку предполагается, что MS DOS 3.0 не будет использоваться на маши- нах, более ранних, чем AT, то использование этих кодов ограничи- вает совместимость Ваших программ. Тем не менее, набор процедур, предназначенный только для MS DOS 3.0 может дополняться поверх обычных процедур обработки ошибок. В [1.1.3] показано как прог- рамма может определить версию MS DOS, в которой она работает. Наконец, имейте ввиду, что процесс может передавать код завер- шения вызвавшему его процессу. Термин процесс относится к взаимо- действующим программам. Например, когда одна программа загружает и запускает другую с помощью функции EXEC, то запускаемая прог- рамма называется потомком, а запускающая программа - родителем. Родителю может потребоваться информация о том, как завершился потомок. Чтобы использовать эту возможность, поместите желаемый код завершения в AL и выполните функцию 4CH прерывания 21H для завершения программы. Когда управление будет возвращено родителю, то он выполнит функцию 4DH прерывания 21H (без входных регистров) и в AL будет получен код завершения, который может затем быть проанализирован. Кроме того, AH будет содержать информацию о том, как завершился потомок: 0 - для нормального завершения, 1 - по Ctrl-Break, 2 - по критической ошибке устройства и 3 - с помощью функции 31H, оставляющей задачу резидентной. Если программа завершилась с помощью этой функции (а не 20H - см. обсуждение в [1.3.4]), то MS DOS получает код выхода и он может быть включен в обработку командным файлом с помощью подко- манды IF. Эта подкоманда позволяет условное исключение других команд из командного файла. Код выхода рассматривается как номер ERRORLEVEL и условные операции выполняются в зависимости от того, больше он или нет определенного числа. С помощью этой возможности командные файлы могут прекращать обработку и выводить сообющение о возникновении ошибки в одной из запущенных программ. Более подробная информация приведена в разделе "Команды пакетной обра- ботки" руководства по операционной системе. Раздел 3. Использование специальных устройств ввода/вывода. Имеется огромное количество устройств ввода/вывода, которые могут быть присоединены к IBM PC, включая мышь, джойстик, графо- построители и т.д. В данном разделе обсуждаются только те уст- ройства, которые специально поддерживаются оборудованием IBM PC. Сюда относятся кассетные магнитофоны, световое перо и другие устройства, которые могут быть присоединены через игровой порт. Адреса портов, относящиеся к другим устройствам, обсуждаются в других разделах этой книги, относящихся именно к данным устройст- вам. Распределение адресов портов в основном одно и то же для всех типов IBM PC: Адрес порта Функция 00-0F микросхема DMA 8237 (не для PCjr) 20-2F микросхема прерываний 8259 (AT контроллер #1: 20-3F) 40-4F микросхема таймера 8253/8254 60-6F микросхема PPI 8255 (AT использует только адреса клавиатуры 70-7F часы реального времени (только AT) 80-83 регистры страниц DMA (не для PCjr) A0-BF микросхема прерываний #2 (только AT) C0-C7 микросхема звука SN76496 (только PCjr) F0-FF PCjr - контроллер НГМД, AT - управление математиче- ским сопроцессором 1F0-1F8 фиксированный диск AT 200-20F игровой адаптер 278-27F AT коммуникационный порт #2 2F8-2FF коммуникационный порт COM2 (COM1 для PCjr) 320-32F фиксированный диск XT 378-37F адаптер параллельного принтера для PC, XT, AT 3B0-3BF монохромный/параллельный адаптеры (не для PCjr) 3D0-3DF цветной графический адаптер 3F0-3F7 контроллер НГМД 3F8-3FF коммуникационный адаптер COM1 (модем PCjr) 7.3.1 Чтение/запись с кассетного магнитофона. Только очень немногие IBM PC и PCjr используют кассетный маг- нитофон, а XT и AT не поддерживают его вообще. Помимо того, что он очень ненадежен, обмен с кассетным магнитофоном возможен толь- ко последовательный, но не с прямым доступом. Тем не менее, могут быть причины для программирования кассетного магнитофона на PCjr. Имейте ввиду, что кассетные операции используют канал 2 микросхе- мы таймера 8253 [2.1.1], поэтому не пытайтесь одновременно ис- пользовать этот канал для других целей. Отметим также, что при операции чтения с кассеты, запрещено прерывание времени суток, поэтому счетчик времени суток BIOS будет давать неверное значе- ние. Высокий уровень. Хотя кассетные файлы обрабатываются совершенно по-другому чем дисковые файлы, однако команды доступа к ним совершенно аналогич- ны. На кассету могут записываться только программные файлы и пос- ледовательные файлы данных. Последние могут включать файлы изоб- ражения памяти. Отметим, что данные не могут добавляться к после- довательным файлам. При создании, именам файлов даются следующие однобайтные расширения: .B программа на Бейсике .P защищенная программа на Бейсике .A программа на Бейсике в формате ASCII .M файл изображения памяти .D последовательный файл данных Для сохранения файла на кассете напишите SAVE "CAS1:имяфайла". Для загрузки программы - LOAD "CAS1:имяфайла". В последнем случае лента прогоняется до тех пор, пока нужный файл не будет найден, при этом имя каждого встреченного файла будет выводиться на экран (кассеты не используют каталоги). Если запросить несуществующий файл, то будет выведен полный список файлов на кассете. Средний уровень. BIOS работает с кассетной лентой порциями в 256-байтные блоки. Набору блоков предшествует "лидер", который состоит из 256 байтов ASCII 1. Лидер завершается нулевым битом синхронизации. Затем следует байт синхронизации со значением 16H, а затем 256 байтов данных. После этого идут 2 байта контроля ошибок, а затем новый блок данных, сопровождающийся парой байт проверки ошибок и т.д. Вся последовательность завершается четырехбайтным "хвостом", содержащим коды ASCII 1. Для чтения данных с кассеты на до использовать функцию 2 пре- рывания 15H. Нет необходимости открывать файл, как это делается при дисковых операциях. ES:BX указывают на буфер в памяти, куда будут посылаться данные, а CX - число байтов, которые надо счи- тать. При возврате DX сообщит сколько байтов прочитано на самом деле, а ES:BX будут указывать на последний считанный байт плюс 1. Флаг переноса будет равен 0, если чтение прошло успешно, а в противном случае AH будет содержать 1, если проблема с контролем ошибки, 2 - при ошибке чтения данных и 3 - при отсутствии данных на ленте. Функция 3 прерывания 15H записывает данные на кассету. ES:BX указывают на первый байт данных, а CX содержит число байтов, которое надо записать. При возврате ES:BX указывают на байт, следующий за последним записанным. Мотор управляется функциями 0 (включение) и 1 (выключение) прерывания 15H. Для этих функций нет выходных регистров. 7.3.2 Чтение позиции светового пера. Хотя очень немногие компьютеры оснащены световым пером, тем не менее это одно из немногих вспомогательных устройств, которое поддерживается как оборудованием, так и операционной системой. Световое перо работает с помощью небольшого оптического детектора на кончике пера. По ходу сканирования экрана электронным лучом инициируется импульс оптического детектора, когда пучок достигает точки экрана, над которой находится перо. Время возникновения этого импульса, относительно сигналов горизонтальной и вертикаль- ной синхронизации, позволяет определить позицию светового пера. Высокий уровень. Бейсик может определять позицию светового пера двумя способа- ми. При первом программа непрерывно определяет статус пера. При втором, когда перо используется, то управление временно передает- ся процедуре, обеспечиваемой Вашей программой. Для непрерывного контроля за пером надо использовать оператор PEN как функцию в форме X = PEN(n), где n - кодовый номер, определяющий какую ин- формацию Вы хотите получить о пере и его позиции. Возможные зна- чения n такие: 0 возвращает -1, если перо было выключено со времени послед- него запроса, 0 - если нет 1 возвращает последнюю координату x (0-319 или 0-639), в ко- торой перо было включено (оно могло быть впоследствии передвинуто, если оставалось включенным) 2 возвращает последнюю координату y (0-199), в которой перо было включено. 3 возвращает -1, если перо включено и 0 - если нет 4 возвращает текущую x координату (0-319 или 0-639) пера 5 возвращает текущую y координату (0-199) пера 6 возвращает позицию - номер строки (1-24), в которой перо было последний раз активизировано 7 возвращает позицию - номер столбца (1-40 или 1-80), в ко- торой перо было последний раз активизировано 8 возвращает текущую позицию - номер строки (1-24) 9 возвращает текущую позицию - номер столбца (1-40 или 1-80) В данном примере определяется включено ли перо, и если это так, то берется текущее его положение: 100 IF NOT PEN(3) THEN 130 'проверяем включено ли перо 110 X = PEN(4) 'получаем координату точки по оси x 120 Y = PEN(5) 'получаем координату точки по оси y 130 ... 'продолжаем программу Более гибкие возможности использования светового пера предос- тавляются оператором ON PEN GOSUB. Этот оператор указывает номер строки, в которой начинается процедура, активизируемая при вклю- чении пера. Бейсик достигает этого проверкой состояния пера после выполнения каждой его инструкции. Процедура может получить пози- цию пера и предпринять требуемые действия. Когда процедура закан- чивается, то программа продолжается с того места, где она была при включении пера. ON PEN GOSUB не работает до тех пор, пока она не активизирова- на оператором PEN ON. PEN OFF отменяет ее работу. Смысл этого состоит в том, что постоянная проверка статуса пера замедляет работу программы, поэтому ее надо осуществлять только когда это необходимо. Если программа начинает выполнять критичекую часть кода, когда нельзя использовать процедуру ON PEN GOSUB, напишите PEN STOP. В этом случае будет продолжаться проверка статуса пера, и если перо будет включено, то этот факт будет запомнен. Однако пока не будет встречен оператор PEN ON, управление не будет пере- даваться процедуре ON PEN GOSUB. Данный пример вызывает остановку программы, когда нажата кноп- ка на световом пере. Точка в позиции светового пера включается процедурой, обрабатывающей включение светового пера. 100 ON PEN GOSUB 5000 'устанавливаем процедуру для светового 110 PEN ON 'пера и включаем режим отслеживания его . . 5000 '''процедура обработки светового пера 5010 X = PEN(4) 'получаем координату X 5020 Y = PEN(5) 'получаем координату Y 5030 PSET(X,Y) 'включить эту точку 5040 RETURN ' Средний уровень. Функция 4 прерывания 10H BIOS сообщает текущую позицию свето- вого пера. У нее нет входных регистров. При возврате AX содержит 0, если перо не включено и 1 - если получены новые значения для его позиции. Возвращается два набора координат, позиции точки и позиции строки и столбца. Позиции символа содержатся в DX, причем DH содержит строку (0-24), а DL - столбец (0-79). Позиция точки содержится в CH и BX, причем CH содержит вертикальную координату (0-199), а BX - горизонтальную (0-319 или 0-639, в зависимости от режима терминала). ;---читаем и запоминаем положение светового пера MOV AH,4 ;номер функции INT 10H ;прерывание BIOS CMP AH,1 ;новая позиция? JE NO_READING ;если нет, то уходим MOV COL,BX ;сохраняем горизонтальную координату MOV CL,CH ;помещаем вертикальную координату MOV CH,0 ;в CX MOV ROW,CX ;сохраняем вертикальную координату Низкий уровень. По своей сути световое перо является расширением видеосистемы и как таковое использует микросхему контроллера CRT 6845. Позиция светового пера дается одним 2-хбайтным значением, хранящимся в регистрах 10H (старший байт) и 11H (младший байт) микросхемы. В [4.1.1] объясняется как читать регистры микросхемы. Посмотрите пример. Порт с адресом 3DCH устанавливает задвижку светового пера, а с номером 3DBH - сбрасывает ее. ;---проверка светового пера и чтение его позиции MOV DX,3DAH ;указываем на регистр статуса IN AL,DX ;получаем информацию TEST AL,4 ;проверяем выключатель JNZ NOT_SET ;на выход TEST AL,2 ;проверяем триггер JZ NOT_SET ;на выход SUB DX,7 ;указываем на регистр адреса 6845 MOV AL,10H ;запрос на старший байт позиции пера OUT DX,AL ;посылаем запрос INC DX ;указываем на регистр данных 6845 IN AL,DX ;получаем значение XCNG AH,AL ;запоминаем его в AH DEC DX ;возвращаемся к адресному регистру MOV AL,11H ;теперь хотим получить младший байт OUT DX,AL ;посылаем запрос INC DX ;назад к регистру данных IN AL,DX ;теперь это значение в AX 7.3.3 Получение аналогового ввода через игровой порт. Игровой порт может поддерживать 2 джойстика или 4 "весла". Для джойстика он сообщает две координаты и статус двух кнопок; для весла он сообщает одну координату и статус одной кнопки. Несколь- ко вспомогательных устройств, таких как графическое табло, также может быть подключено к игровому порту; их работа может осуществ- ляться параллельно с работой джойстика. Данный раздел посвящен чтению координат, а в следующем обсуждается как получить статус кнопок. Высокий уровень. Функция STICK возвращает позиции по осям, указываемую следую- щими кодовыми номерами: 0 ось X джойстика A 1 ось Y джойстика A 2 ось X джойстика B 3 ось Y джойстика B Вам нужно написать, например, X = STICK(0) и в X будет содержать- ся значение координаты X для джойстика A. Но эта функция имеет ловушку, о которой Вам необходимо знать. Только при использовании кода 0 действительно читаются координаты джойстика, при этом читаются все 4 значения. Кодовые номера 1-3 просто сообщают пока- зания, прочитанные кодом 0. Чтобы получить последние 3 координаты Вам необходимо перед этим использовать функцию X = STICK(0), даже если Вам не нужно знать значение, возвращаемое кодом 0. Джойстики отличаются по своим физическим характеристикам, поэтому необходимо настраивать их, чтобы их предельные положения совпадали с границами экрана. В следующем примере показано как это делается. В примере непрерывно рисуется точка, в позиции, указываемой джойстиком, действие, которое требуется, чтобы диапа- зон значений, принимаемых игровым портом, преобразовывался в диапазон позиций экрана. 100 '''получаем предельные показания джойстика 110 STRIG ON 'разрешаем кнопки 120 V= STRIG(0) 'чистим старые показания 130 PRINT "Briefly push button 1 when stick is farthest to left" 140 XLEFT = STICK(0) 'получаем самое левое значение 150 IF STRIG(0) = 0 THEN 140 'ждем нажатия кнопки 160 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON 170 PRINT "Briefly push button 1 when stick is farthest to right" 180 XRIGHT = STICK(0) 'получаем самое правое значение 190 IF STRIG(0) = 0 THEN 180 'ждем нажатия кнопки 200 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON 210 PRINT "Briefly push button 1 when stick is farthest to top" 220 V = STICK(0): YTOP = STICK(1) 'самое верхнее значение 230 IF STRIG(0) = 0 THEN 220 'ждем нажатия кнопки 240 STRIG OFF: FOR N = 1 TO 1000: NEXT: STRIG ON 250 PRINT "Briefly push button 1 when stick farthest to bottom" 260 V = STICK(0): YBOTTOM = STICK(1) 'самое нижнее значение 270 IF STRIG(0) = 0 THEN 260 'ждем нажатия кнопки 280 STRIG OFF 'закончили 290 '''получаем множители для установки на размер экрана 300 XRIGHT = XRIGHT - XLEFT 'горизонтальный размер 310 XMULTIPLIER = 320/XRIGHT 'вычисляем число точек на деление 320 YBOTTOM = YBOTTOM - YTOP 'вертикальный размер 330 YMULTIPLIER = 200/B/YBOTTOM 'число точек на деление 340 '''теперь вычисляем координаты в режиме умеренного разрешения 350 X = STICK(0) 'получаем горизонтальную позицию 360 Y = STICK(1) 'получаем вертикальную позицию 370 X = (X - XLEFT)*XMULTIPRIER 'приводим к экрану 380 Y = (Y - YTOP)*YMULTIPRIER ' 390 PSET(X,Y) 'выводим точку в нужной позиции 400 GOTO 350 'повторяем Средний уровень. Только AT предоставляет поддержку джойстика на уровне опера- ционной системы. Это функция 84H прерывания 15H, которая возвра- щает координаты, причем: AX = координата X джойстика A BX = координата Y джойстика A CX = координата X джойстика B DX = координата Y джойстика B При входе поместите в DX 1. Когда в DX содержится 0, то эта функ- ция возвращает состояние кнопок джойстика [7.3.4]. При возврате флаг переноса установлен, когда у машины нет игрового порта. Низкий уровень. Информация о координатах обоих джойстиков или всех четырех весел хранится в одном байте, доступ к которому осуществляется через порт 201H. Вот значение его битов: Бит Джойстик Весло 3 координата Y джойстика B координата весла D 2 координата X джойстика B координата весла C 1 координата Y джойстика A координата весла B 0 координата X джойстика A координата весла A Координата может описываться одним битом за счет измерения временных интервалов. Пошлите в порт байт с произвольным значе- нием. Это приведет к тому, что младшие 4 бита обнулятся. Затем постоянно считывайте значение из порта, замеряя интервал времени, через который интересующий Вас бит станет равным 1. Этот интервал пропорционален позиции джойстика по интересующей Вас оси. Макси- мальны еинтервалы соответствуют нижней позиции по оси Y и правой позиции по оси X. Независимо от позиции, биты меняются от 0 к 1 очень быстро, по сравнению с механической скоростью перемещения джойстика или весла. Поэтому программа может с большой точностью получить сначала позицию координаты Y, а затем позицию координаты X. Нет необходимости тестировать каждую координату отдельно. В данном примере определяется координата X джойстика A. ;---получаем координату X джойстика A MOV DX,201H ;адрес игрового порта OUT DX,AL ;посылаем в порт произвольное значение MOV AH,1 ;проверяем бит 1 MOV SI,0 ;инициализируем счетчик NEXT: IN AL,DX ;читаем значение из порта TEST AL,AH ;проверяем бит 1 JE FINISHED ;выход, когда бит установлен INC SI ;иначе, увеличиваем счетчик LOOP NEXT ;на начало цикла FINISHED: 7.3.4 Получение цифрового ввода из игрового порта. Игровой порт поддерживает два джойстика или четыре "весла", а также ряд графических устройств. При этом может определяться статус до четырех кнопок устройств. Проверка состояния кнопок может быть сложным делом, поскольку программа может не иметь возможности постоянно проверять их, а кнопка может быть нажата и отпущена, пока программа занята другими делами. Может быть созда- на специальная процедура для решения этой проблемы. Статус кнопок автоматически читается несколько раз в секунду, без специального запроса на это программы; когда оказывается, что кнопка нажата, то управдение передается процедуре, которая определяет какая кнопка нажата и предпринимает нужные действия. Высокий уровень. Бейсик использует оператор STRIG для чтения статуса кнопок. Оператор STRIG достаточно хитрый, чтобы обнаружить нажатие кноп- ки, даже если программа в данный момент не занимается статусом кнопки, т.е. программа может запросить: "Было ли нажатие кнопки, со времени моего последнего запроса?" Это свойство очень полезно для видеоигр, поскольку программа может заниматься манипуляциями с экраном, не заботясь о постоянной проверке статуса кнопок. Однако это существенно замедляет скорость выполнения программы, поскольку проверка статуса кнопок осуществляется после выполнения каждого оператора. По этой причине, STRIG работает только когда он преднамеренно включен, а он может включаться и выключаться по ходу программы. STRIG работает двумя способами. Во-первых, он может работать как функция, которая непосредственно читает текущие значения кнопок, в форме X = STRIG(n). Здесь n - кодовый номер: 0 Кнопка A1 нажата со времени последнего вызова 1 Кнопка A1 в данный момент отпущена 2 Кнопка B1 нажата со времени последнего вызова 3 Кнопка B1 в данный момент отпущена 4 Кнопка A2 нажата со времени последнего вызова 5 Кнопка A2 в данный момент отпущена 6 Кнопка B2 нажата со времени последнего вызова 7 Кнопка B2 в данный момент отпущена Во всех случаях функция возвращает -1, если описание применимо и 0 - если нет. Второй способ использования STRIG это форма, в которой он автоматически переключает на процедуру при нажатии кнопки. Надо написать ON STRIG(n) GOSUB номерстроки. Номер строки дает началь- ный номер строки процедуры. Число n относится к кнопке, где 0 = A1, 2 = B1, 4 = A2 и 6 = B2. Каждая кнопка может обрабатываться своей процедурой или может быть одна процедура для всех кнопок. Для активизации функции STRIG включите в программу оператор STRIG(n) ON. В качестве значения n используются четыре перечис- ленных кода. Чтобы отменить его (ускоряя работу программы) напи- шите STRIG(n) OFF. Имеется также третья возможность. STRING(n) STOP приводит к тому, что нажатие кнопки запоминается, но никаких действий не предпринимается до очередного оператора STRING(n) ON. Это свойство предохраняет от нежелательных перерывов из-за опера- тора ON STRING GOSUB. Тем не менее, при выполнении условия STRIG(n) STOP программа замедляется. Следующий пример показывает действие ON STRIG GOSUB. Пример пункта [7.3.3] содержит строки, показывающие форму X = STRIG. 100 ON STRIG(0) GOSUB 5000 'переход на 5000 при нажатии . 'кнопки A1 200 STRIG(0) ON 'включаем проверку нажатия кнопки . 300 STRIG(0) STOP 'отменяем уход на процедуру . 400 STRIG(0) ON 'возобновляем уход на процедуру . 500 STRIG(0) OFF 'отменяем проверку нажатия кнопки . 5000 '''здесь находится процедура обработки нажатия кнопки A1 . 5500 RETURN 'возврат к тому месту, откуда попали сюда Средний уровень. Только AT предоставляет поддержку джойстика на уровне опера- ционной системы. Функция 84H прерывания 15H возвращает установку кнопок в битах 4-7 регистра AL, как показано ниже. При входе DX должен содержать 0; когда DX содержит 1, то вместо этого возвра- щаются координаты джойстика [7.3.3]. При возврате регистр перено- са устанавливается, когда машина не имеет игрового порта. ;---проверяем кнопку #2 джойстика B (бит 7) MOV AH,84H ;номер функции MOV DX,0 ;запрос состояния кнопок INT 15H ;вызов функции JC NO_JOYSTICK ;если нет джойстика, то на выход TEST AL,10000000B ;проверяем бит 7 JNZ BUTTON_DOWN ;переход если кнопка нажата Низкий уровень. Биты 7-4 порта с адресом 201H содержат статус кнопок, связан- ных с игровым портом. Значение битов меняется в зависимости от того, присоединены ли джойстики или весла: Бит Джойстик Весло 7 Кнопка #2 джойстика B Кнопка весла D 6 Кнопка #1 джойстика B Кнопка весла C 5 Кнопка #2 джойстика A Кнопка весла B 4 Кнопка #1 джойстика A Кнопка весла A Программе нужно просто прочитать значение из порта и проверить установку соответствующих битов: MOV DX,201H ;адрес порта игрового адаптера IN AL,DX ;получаем значение из него TEST AL,0010B ;проверяем бит 1 (кнопка A2 нажата?) JNZ BUTTON_A2 ;если да, то на процедуру обработки Программа имеет обычно более важные дела, чем постоянно проверять игровой порт, однако настолько же быссмысленно время от времени проверять порт, рассовывая процедуру по разным частям программы. Чтобы получить эффект отлова нажатия кнопок, аналогичный описан- ному в Бейсике, Вам придется создать дополнение к прерыванию времени суток, как описано в [2.1.7]. Прерывание обычно выпол- няется 18.2 раза в секунду и каждый раз Вы можете проверять игро- вой порт и предпринимать нужные действия при необходимости. Приложения. Приложение А. Двоичные и шестнадцатиричные числа и адресация памяти. Основной единицей хранения данных в компьютере является бит. В большинстве микрокомпьютеров восемь битов объединены в байт, при этом каждый бит байта может быть установлен или "включен" (= 1) или сброшен или "выключен" (= 0), допуская 256 разных вариантов. Таким образом, в одном байте можно представить 256 разных симво- лов (расширенный набор кодов ASCII) или целое число в диапазоне от 0 до 255. Хотя мы привыкли записывать эти числа в десятичной форме, они могут записываться также в двоичной или шестнадцати- ричной форме - их значения при этом не изменяются, а программы могут с одинаковой легкостью читать эти значения как в той, так и в другой форме. Вместо того, чтобы говорить, что в одном байте могут храниться числа от 0 до 255, можно сказать, что могут хра- ниться двоичные числа от 00000000 до 11111111 или шестнадцатирич- ные числа от 00 до FF. Поскольку можно перепутать разные формы, то двоичные и шестнадцатиричные числа отмечаются специальным образом. В языке ассемблера за двоичными числами следует буква B, а за шестнадцатиричными числами - буква H, например, 11111111B или FFH. Бейсик фирмы Microsoft предваряет шестнадцатиричные числа символами &H, например &FFH; к сожалению, он не распознает числа в двоичной форме. Двоичные числа: Когда содержимое байта представляется в двоичной форме, то требуется 8 цифр. Каждая цифра соответствует одному биту, которые нумеруются от 0 до 7. Как и в десятичных числах цифры распола- гаются справа налево, от младших к старшим разрядам. В отличии от десятичных чисел, в которых каждая последующая цифра весит в 10 раз больше своей соседки справа, двоичные цифры имеют только вдвое больший вес. Таким образом, самая правая цифра считает единицы, вторая - двойки, третья - четверки и т.д., до значения 128 для восьмой цифры байта. Это означает, что если первая цифра равна 1, то прибавление к ней 1 приводит к тому, что она станет 0, а 1 будет перенесена во вторую цифру, как для десятичных чисел 9 + 1 = 0 и перенос единицы в следующий разряд. Вот как числа первого десятка представляются в двоичной форме: 00000000 0 00000001 1 00000010 2 00000011 3 00000100 4 00000101 5 00000110 6 00000111 7 00001000 8 00001001 9 00001010 10 В этой последовательности большинство нулей слева необязатель- ны, т.е. эту последовательность можно записать и в виде 0, 1, 10, 11, 100, 101 и т.д. Нули включены только для того, чтобы напом- нить Вам, что байт составляется восемью цифрами, соответствующими битам. В то время как набор нулей и единиц может быть несколько утомительным, Вы можете легче работать с двоичными числами, если будете представлять их себе следующим образом: бит 7 6 5 4 3 2 1 0 значение 128 64 32 16 8 4 2 1 Когда Вы встречаете двоичное число 10000001, то установлены биты 7 и 0. Бит 7 соответствует 128, а бит 0 - 1, поэтому десятичное значение байта равно 129. Если этот байт представляет символ, то он соответствует коду ASCII 129, который представляет букву u с умляутом (в альтернативной кодировке ГОСТа - букву Б). Наоборот, чтобы определить цепочку битов для буквы A, которая равна ASCII Приложение Б. Битовые операции в Бейсике. В Бейсике нельзя использовать числа в двоичной форме. Он расс- матривает цепочку битов 11000000 как 11 миллионов, а не как 192. Однако манипуляции с цепочками битов часто необходимы при прог- раммировании, поскольку требуется читать и изменять содержимое статусных байтов и статусных регистров. В большинстве случаев к цепочкам битов применяются две логи- ческие операции. Это операции ИЛИ (OR) и И (AND) и обе они дос- тупны в Бейдиапазоне от 0 до 255. Хотя мы привыкли записывать эти числа в десятичной форме, они могут записываться также в двоичной или шестнадцати- ричной форме - их значения при этом не изменяются, а программы могут с одинаковой легкостью читать эти значения как в той, так и в другой форме. Вместо того, чтобы говорить, что в одном байте могут храниться числа от 0 до 255, можно сказать, что могут хра- ниться двоичные числа от 00000000 до 11111111 или шестнадцатирич- ные числа от 00 до FF. Поскольку можно перепутать разные формы, то двоичные и шестнадцатиричные числа отмечаются специальным образом. В языке ассемблера за двоичными числами следует буква B, а за шестнадцатиричными числами - буква H, например, 11111111B или FFH. Бейсик фирмы Microsoft предваряет шестнадцатиричные числа символами &H, например &FFH; к сожалению, он не распознает числа в двоичной форме. Двоичные числа: Когда содержимое байта представляется в двоичной форме, то требуется 8 цифр. Каждая цифра соответствует одному биту, которые нумеруются от 0 до 7. Как и в десятичных числах цифры распола- гаются справа налево, от младших к старшим разрядам. В отличии от десятичных чисел, в которых каждая последующая цифра весит в 10 раз больше своей соседки справа, двоичные цифры имеют только вдвое больший вес. Таким образом, самая правая цифра считает единицы, вторая - двойки, третья - четверки и т.д., до значения 128 для восьмой цифры байта. Это означает, что если первая цифра равна 1, то прибавление к ней 1 приводит к тому, что она станет 0, а 1 будет перенесена во вторую цифру, как для десятичных чисел 9 + 1 = 0 и перенос единицы в следующий разряд. Вот как числа первого десятка представляются в двоичной форме: 00000000 0 00000001 1 00000010 2 00000011 3 00000100 4 00000101 5 00000110 6 00000111 7 00001000 8 00001001 9 00001010 10 В этой последовательности большинство нулей слева необязатель- ны, т.е. эту последовательность можно записать и в виде 0, 1, 10, 11, 100, 101 и т.д. Нули включены только для того, чтобы напом- нить Вам, что байт составляется восемью цифрами, соответствующими битам. В то время как набор нулей и единиц может быть несколько утомительным, Вы можете легче работать с двоичными числами, если будете представлять их себе следующим образом: бит 7 6 5 4 3 2 1 0 значение 128 64 32 16 8 4 2 1 Когда Вы встречаете двоичное число 10000001, то установлены биты 7 и 0. Бит 7 соответствует 128, а бит 0 - 1, поэтому десятичное значение байта равно 129. Если этот байт представляет символ, то он соответствует коду ASCII 129, который представляет букву u с умляутом (в альтернативной кодировке ГОСТа - букву Б). Наоборот, чтобы определить цепочку битов для буквы A, которая равна ASCII блоки. Набору блоков предшествует "лидер", который состоит из 256 байтов ASCII 1. Лидер завершается нулевым битом синхронизации. Затем следует байт синхронизации со значением 16H, а затем 256 байтов данных. После этого идут 2 байта контроля ошибок, а затем новый блок данных, сопровождающийся парой байт проверки ошибок и т.д. Вся последовательность завершается четырехбайтным "хвостом", содержащим коды ASCII 1. Для чтения данных с кассеты на до использовать функцию 2 пре- рывания 15H. Нет необходимости открывать файл, как это делается при дисковых операциях. ES:BX указывают на буфер в памяти, куда будут посылаться данные, а CX - число байтов, которые надо счи- тать. При возврате DX сообщит сколько байтов прочитано на самом деле, а ES:BX будут указывать на последний считанный байт плюс 1. Флаг переноса будет равен 0, если чтение прошло успешно, а в противном случае AH будет содержать 1, если проблема с контролем ошибки, 2 - при ошибке чтения данных и 3 - при отсутствии данных на ленте. Функция 3 прерывания 15H записывает данные на кассету. ES:BX указывают на первый байт данных, а CX содержит число байтов, которое надо записать. При возврате ES:BX указывают на байт, следующий за последним записанным. Мотор управляется функциями 0 (включение) и 1 (выключение) прерывания 15H. Для этих функций нет выходных регистров. 7.3.2 Чтение позиции светового пера. Хотя очень немногие компьютеры оснащены световым пером, тем не менее это одно из немногих вспомогательных устройств, которое поддерживается как оборудованием, так и операционной системой. Световое перо работает с помощью небольшого оптического детектора на кончике пера. По ходу сканирования экрана электронным лучом инициируется импульс оптического детектора, когда пучок достигает точки экрана, над которой находится перо. Время возникновения этого импульса, относительно сигналов горизонтальной и вертикаль- ной синхронизации, позволяет определить позицию светового пера. Высокий уровень. Бейсик может определять позицию светового пера двумя способа- ми. При первом программа непрерывно определяет статус пера. При втором, когда перо используется, то управление временно передает- ся процедуре, обеспечиваемой Вашей программой. Для непрерывного контроля за пером надо использовать оператор PEN как функцию в форме X = PEN(n), где n - кодовый номер, определяющий какую ин- формацию Вы хотите получить о пере и его позиции. Возможные зна- чения n такие: 0 возвращает -1, если перо было выключено со времени послед- него запроса, 0 - если нет 1 возвращает последнюю координату x (0-319 или 0-639), в ко- торой перо было включено (оно могло быть впоследствии передвинуто, если оставалось включенным) 2 возвращает последнюю координату y (0-199), в которой перо было включено. 3 возвращает -1, если перо включено и 0 - если нет 4 возвращает текущую x координату (0-319 или 0-639) пера 5 возвращает текущую y координату (0-199) пера 6 возвращает позицию - номер строки (1-24), в которой перо было последний раз активизировано 7 возвращает позицию - номер столбца (1-40 или 1-80), в ко- торой перо было последний раз активизировано 8 возвращает текущую позицию - номер строки (1-24) 9 возвращает текущую позицию - номер столбца (1-40 или 1-80) В данном примере определяется включено ли перо, и если это так, то берется текущее его положение: 100 IF NOT PEN(3) THEN 130 'проверяем включено ли перо 110 X = PEN(4) 'получаем координату точки по оси x 120 Y = PEN(5) 'получаем координату точки по оси y 130 ... 'продолжаем программу Более гибкие возможности использования светового пера предос- тавляются оператором ON PEN GOSUB. Этот оператор указывает номер строки, в которой начинается процедура, активизируемая при вклю- чении пера. Бейсик достигает этого проверкой состояния пера после выполнения каждой его инструкции. Процедура может получить пози- цию пера и предпринять требуемые действия. Когда процедура закан- чивается, то программа продолжается с того места, где она была при включении пера. ON PEN GOSUB не работает до тех пор, пока она не активизирова- на оператором PEN ON. PEN OFF отменяет ее работу. Смысл этого состоит в том, что постоянная проверка статуса пера замедляет работу программы, поэтому ее надо осуществлять только когда это необходимо. Если программа начинает выполнять критичекую часть кода, когда нельзя использовать процедуру ON PEN GOSUB, напишите PEN STOP. В этом случае будет продолжаться проверка статуса пера, и если перо будет включено, то этот факт будет запомнен. Однако пока не будет встречен оператор PEN ON, управление не будет пере- даваться процедуре ON PEN GOSUB. Данный пример вызывает остановку программы, когда нажата кноп- ка на световом пере. Точка в позиции светового пера включается процедурой, обрабатывающей включение ERROR ;на обработку ошибки INC BX ;увеличиваем указатель LOOP NEXT_CHAR ;выводим следующий символ Стандартное прерывание MS DOS для вывода на принтер это функ- ция 5 прерывания 21H. Просто поместите символ в DL и выполните прерывание. Эта функция всегда выводит на LPT1 и у нее нет возв- ращаемых регистров. ;---вывод данных на LPT1 MOV AH,5 ;номер функции MOV DL,CHAR ;готовим печатаемый символ INT 21H ;посылаем его на пр ;N,1)*2^(N-1) 2040 NEXT 2050 RETURN Приложение В. Основные сведения об языке ассемблера. Читатель этой книги, не знакомый с языком ассемблера, скоро поймет, что многие программистские трюки не могут быть достигнуты другими средствами. Хотя изучение языка ассемблера требует от- дельной книги, в этом приложении приводятся основные понятия, которые помогут новичкам разобраться в примерах на этом языке. Внимательный просмотр разделов, посвященных среднему и низкому уровням, даст Вам возможность получить представление о том, как работает ассемблер, после чего намного легче изучить разные част- ные вопросы. Здесь обсуждаются не все ассемблерные инструкции, встречающиеся в программах, но Вы обнаружите, что около 95 % инструкций, встреченных Вами в программах, описаны здесь, а зна- чение остальных может быть понято благодаря комментариям к прог- раммам. Микропроцессор 8088 имеет 13 16-разрядных регистров, каждый из которых имеет свои функции. В то время как в языках высокого уровня Вы можете поместить два числа в переменные, а затем сло- жить эти переменные, то в языке ассемблера эти числа помещаются в регистры микропроцессора, а затем складываются значения, содержа- щиеся в регистрах. Все операции в языке ассемблера состоят в обмене данных с регистрами, а затем выполнении операций на ре- гистрах, таких как изменение отдельных битов, выполнение арифме- тических операций и т.д. Одной из причин высокой эффективности языка ассемблера является хранение данных в регистрах микропро- цессора; компиляторы имеют тенденцию возвращать все значения в память после выполнения операции, а доступ к памяти требует боль- шого времени. На рис. В-1 показаны 13 регистров микропроцессоров 8088 и 80286 (последний имеет дополнительные средства для много- задачной работы, которые мы не будем рассматривать здесь). Регистры AX, BX, CX и DX являются регистрами общего назначе- ния. Их особенность состоит в том, что операции могут произво- диться не только над содержимым всего регистра, но также и над половиной. Каждый из четырех регистров делится на старшую и млад- шую части, например, AH обозначает старшую половину регистра AX, а AL - младшую. Точно так же ассемблерная программа может иметь доступ к BH, BL, CH, CL, DH и DL. Это свойство очень полезно, поскольку часто программе приходится работать с байтными величи- нами. Регистры BP, SI и DI также достаточно удобны, хотя они могут принимать только 16-битные значения. Каждый бит регистра флагов сообщает о соответствующем статусе процессора, например, о том, что при выполнении арифметической операции был перенос за разрядную сетку. В общем случае значения помещаются в регистры с помощью инст- рукции MOV. MOV AX,BX пересылает содержимое регистра BX в AX, затирая ранее содержащееся в AX значение. MOV AH,BL приводит к пересылке байта из регистра в регистр, но MOV AX,BL - недопусти- мая инструкция, так как значения должны иметь одинаковый размер. Инструкция MOV можеть также передавать значения из памяти, напри- мер, MOV AX,ACCT_NUMBER. Здесь ACCT_NUMBER - имя переменной, которую создал программист, совсем как в языке высокого уровня. Переменная создается оператором вида ACCT_NUMBER DW 0. Этот опе- ратор оставляет место для слова (двух байтов), присваивая им значение 0. Другие допустимые символы в этом операторе это DD - для двойного слова и DB - для байта или строк. Ассемблер следит за адресами переменных, поэтому при ассемблировании оператора MOV AX,ACCT_NUMBER имя переменной заменяется на ее адрес. Работа с именами переменных - самый простой способ идентифика- ции данных в программах на языке ассемблера. Но имеются различные способы хитрой адресации, которые позволяют программе хранить массивы или использовать указатели. Например, MOV AX,[BX][SI] посылает в AX значение, которое содержится по смещению, равному сумме значений регистров BX и SI. Но от чего отсчитывать смеще- ние? Ответ заключается в том, что все данные собраны в одну часть программы, а весь исполняемый код - в другую. Часть, отведенная под данные, называется сегментом данных, а под программу - кодо- вым сегментом. Все переменные, отведенные для хранения данных, адресуются через смещение относительно начала сегмента данных. Позиция в памяти, с которой начинается сегмент данных, хранит- ся в регистре DS, одном из четырех сегментных регистров. Как и все остальные регистры микропроцессора он 16-разрядный, поэтому он не может содержать числа, большие чем 65535. Каким же образом сегмент даных может указывать на ячейки памяти, расположенные в верхней части мегабайтного адресного пространства? Ответ состоит в том, что сегментные регистры автоматически умножаются на 16, а результат указывает на место в памяти, с которого начинается сегмент. Таким образом, сегменты всегда выравнены на 16-байтную границу. После того как сегмент установлен, все остальные регист- ры могут содержать смещения, указывающие на любой из следующих 65535 байтов. Регистр дополнительного сегмента (ES) также исполь- зуется для указания на данные, хранящиеся в памяти. Среди ассемблерных инструкций, которые Вы часто будете встре- чать в этой книге, есть инструкции загрузки сегментных и относи- тельных адресов переменных. MOV AX,SEG ACCT_NUMBER помещает зна- чение сегментного регистра, в котором расположен ACCT_NUMBER в AX, а впоследствии это значение будет переслано в DS. MOV BX,OFF- SET ACCT_NUMBER помещает в BX смещение переменной ACCT_NUMBER в сегменте данных. После выполнения этих операций DS:BX будут ука- зывать на ACCT_NUMBER. Если ACCT_NUMBER является одномерным мас- сивом, то для указания на определенный элемент массива может использоваться добавочное смещение. Вы часто будете встречать также инструкцию LEA, предоставляющую другой способ загрузки смещения. Кодовый сегмент содержит последовательность машинных инструк- ций, составляющих программу. Например, инструкция MOV существует в виде нескольких байтов машинного кода, значение байтов которого определяет в какой регистр идет пересылка и откуда. Регистр IP (счетчик команд) содержит величину смещения, которая указывает на ту инструкцию в кодовом сегменте, которая сейчас должна выпол- няться. После выполнения инструкции IP увеличивается таким обра- зом, чтобы он указывал на следующую инструкцию. В простейшей программе счетчик команд будет передвигаться от первого байта кодового сегмента к последнему, где программа и завершится. Но, как и другие программы, программа на языке ассемблера может быть разбита на процедуры (подпрограммы), поэтому счетчик команд может прыгать из одного места кодового сегмента в другое. Когда счетчик команд прыгает в другое место кодового сегмента, то его старое значение должно быть запомнено, с тем чтобы можно было вернуться в нужное место, так как это делает оператор RETURN в Бейсике, возвращая управление в то место, откуда была вызвана процедура. В языке ассемблера процедуре присваивается имя, напр- имер, COMBINE_DATA, и оператор CALL COMBINE_DATA передает управ- ление в процедуру. Процедура завершается инструкцией RET (возв- рат). При вызове процедуры процессор запоминает текущее значение счетчика команд, заталкивая его на стек. Стек это область, используемая для временного хранения данных. После завершения процедуры старое значение счетчика команд берет- ся из стека и выполнение программы продолжается. Стек также со- держится в отдельном сегменте, который, совершенно естественно, называется сегментом стека. Ему соответствует сегментный регистр SS. В регистре SP хранится указатель стека, который всегда указы- вает на вершину стека и изменяется при засылке на стек и выборке из стека. На первый взгляд стек кажется достаточно неуклюжим способом хранения информации, но у него есть два преимущества. Во-первых, доступ к его содержимому намного быстрее, чем к переменным, хра- нящимся в памяти, а, во-вторых, стек может использоваться для многих целей. Он может хранить адреса возврата из процедуры, вложенной в другую процедуру. Впоследствии, то же самое прост- ранство может использоваться программистом для хранения данных, которые должны сейчас обрабатываться, но для которых не хватает места в регистрах микропроцессора. Программа выталкивает содержи- мое регистра на стек командой PUSH, а позднее забирает его оттуда командой POP. В ассемблерных программах, приведенных в этой кни- ге, Вы не раз встретитесь с инструкциями типа PUSH BX и POP DX. Неправильный порядок обмена данными со стеком - лучший способ привести ассемблерную программу к краху. После того как программист на ассемблере установил три сег- ментных регистра (CS, DS и SS) и загрузил данные в регистры мик- ропроцессора он имеет широкий набор встроенных средств, которыми процессор может помочь программисту на ассемблере. Вот наиболее распространенные из них: ADD AX,BX Прибавляет BX к AX. Существует также инструкция вычи- тания (SUB), а также варианты обеих этих инструкций. MUL BL Умножает BL на AX. Имеется также инструкция деления (DIV), а также варианты обеих этих инструкций. INC BL Увеличивает BL на 1. Имеется также инструкция умень- шения (DEC). LOOP XXX Возвращает программу назад к строке помеченной XXX, повторяя процесс столько раз, какое число содержится в CX (аналогично инструкции FOR .. TO .. NEXT в Бей- сике). OR AL,BL Выполняет операцию логического ИЛИ над содержимым регистров AL и BL, причем результат помещается в AL. Имеются также инструкции AND, XOR и NOT. SHL AX,1 Сдвигает все биты, содержащиеся в AX, на одну позицию влево. Это эквивалентно умножению содержимого AX на 2. Другие инструкции сдвигают биты вправо или осу- ществляют циклический сдвиг. Все эти инструкции очень полезны для битовых операций, таких как установка точек экрана. IN AL,DX Помещает в AX байт, обнаруженный в порте, адрес кото- рого указан в DX. Имеется также инструкция OUT. JMP Передает управление в другое место программы, как инструкция GOTO в Бейсике. JMP YYY передает управле- ние на строку программы, имеющую метку YYY. CMP AL,BL Сравнивает содержимое AL и BL. За инструкцией CMP обычно следует инструкция условного перехода. Напри- мер, если за инструкцией CMP следует инструкция JGE, то переход произойдет только если BL больше или равно AL. Инструкция CMP достигает того же результата, что и инструкция IF .. THEN в Бейсике (на самом деле инструкция IF .. THEN переводится интерпретатором Бейсика в инструкцию CMP). TEST AL,BL Проверяет есть ли среди битов, установленных в BL, такие, которые установлены также и в AL. За этой инструкцией обычно следует команда условного перехо- да, так же как за CMP. TEST очень полезен при провер- ке статусных битов (битовые операции очень просто реализуются в языке ассемблера). MOVS Пересылает строку, длина которой содержится в CX, с места, на которое указывает SI, на место, на которое указывает DI. Имеется еще несколько других инструк- ций, связанных с пересылкой и поиском строк. Язык ассемблера обеспечивает несколько вариантов этих инструкций, а также ряд других специальных инструкций. Имеется также целый класс инструкций, называемых псевдооператорами, которые помещают- ся в текст программы с целью указания ассемблеру как обрабатывать данную программу. Например, один из типов псевдооператоров авто- матически вставляет часто используемый кусок кода по всей прог- рамме. Такая порция кода называется макросом и именно это свойст- во ассемблера дало ему название "макроассемблер". И, наконец, ассемблер имеет возможность, которой завидуют (или, по крайней мере, должны завидовать) все кто программирует только на языках высокого уровня. Имеется ввиду возможность опти- мальным образом использовать прерывания операционной системы. Ведь это ничто иное, как готовые процедуры. Однако вместо того, чтобы вызывать их по CALL, они вызываются инструкцией INT. INT21H вызывает прерывание с шестнадцатиричным номером 21. Имеется ряд таких прерываний, как в базовой системе ввода/вывода ПЗУ, так и в операционной системе, причем некоторые из этих процедур необычай- но мощны. На самом деле некоторые из них настолько тесно связаны с системой, что Вы практически не можете сами написать эквива- лентную процедуру. Языки высокого уровня позволяют использовать многие из этих прерываний. Они используют их для вывода на экран, приема ввода с клавиатуры и доступа к дискам. Но многие действи- тельно полезные прерывания игнорируются языками высокого уровня, например такие, которые позволяют запустить из одной программы другую. Некоторые трансляторы (такие как Lattice C или Turbo Pascal) позволяют доступ к этим прерываниям, если Вы знаете как их готовить и Вы можете использовать разделы среднего уровня этой книги для этой цели. Перед вызовом прерывания некоторая информация должна быть помещена в регистры процессора. Например, прерывание, верикально сдвигающее экран, должно знать размеры сдвигаемого окна, число строк на которое его надо сдвинуть и т.д. Эти значения часто называют входными регистрами. Снова и снова Вы будете встречать слова "при входе BX должен содержать ...", описывающие специфика- цию входных регистров. Аналогично, при возврате из прерывания некоторые регистры возвращают значения или статусную информацию. Они называются выходными регистрами и мы описываем их словами "при выходе AX содержит ...". Зачастую одно прерывание содержит много функций. В частности, операционная система впихнула практи- чески все свои возможности в прерывание 21H. Поэтому при вызове прерывания необходимо указывать номер функции. Все прерывания (как BIOS так и DOS) передают номер функции в AH (иногда в AL содержится номер подфункции). Все сказанное в основном служит только чтобы дать первое представление о предмете. Но если Вы будете внимательно просмат- ривать простейшие примеры, содержащиеся в этой книге, то Вы пой- мете стоящую за ними логику. Язык ассемблера имеет репутацию трудного языка. Но то, что Вы только что прочитали - настоящая чепуха. Имеется достаточно сложностей и в языках высокого уровня. И если ошибки в ассемблерной программе бывает очень сложно обна- ружить, то в основном это связано с тем, что сам текст программы намного длиннее, чем эквивалентный текст на языке высокого уров- ня (однако ассемблерный код намного плотнее). В настоящее время многие профессионалы пишут программы на языке C, затем анализи- руют эффективность и переписывают критические кусочки программы, которые расходуют много времени, на языке ассемблера. Невозмож- ность написания таких ассемблерных процедур может иногда свести усилия программиста к нулю. Поэтому найдите хороший букварь по ассемблеру и приступайте! Возможно самой большой наградой для Вас станет момент, когда Вы наконец действительно станете понимать как же работает компьютер. Приложение Г. Включение ассемблерных процедур в программы на Бейсике. Процедуры на языке ассемблера состоят из строк байтов машинно- го кода. При выполнении этой процедуры Бейсик передает управление из последовательности инструкций, составляющих программу на Бей- сике, в то место, где хранятся инструкции, которые могут быть декодированы в последовательность инструкций языка ассемблера. При завершении ассемблерной процедуры управление возвращается в то место бейсиковской программы, откуда была вызвана процедура. В этой книге ассемблерные процедуры, используемые в программах на Бейсике, приведены в двух видах. В обоих видах процедуры вклю- чены в программу, а не хранятся в виде отдельного дискового фай- ла. При первом способе требуется, чтобы коды процедуры находились в отдельном месте в памяти, а при втором, менее принятом, этого не требуется. В первом способе процедура помещается в операторы DATA и прог- рамма пересылается в неиспользуемую часть памяти, а затем вызы- вается оператором CALL. Надо позаботиться о том, чтобы код проце- дуры не накладывался на какие-либо данные и наоборот. Обычное решение этой проблемы состоит в том, что процедура помещается в те адреса памяти, к которым Бейсик не может получить доступ. Поскольку интерпретатор Бейсика не может иметь доступ за пределы 64K, то для системы, скажем, с памятью 256K, нужно поместить процедуру в старшие 64K. Для систем с памятью 128K Вы должны вычислить сколько памяти требуется операционной системе, Бейсику и драйверам устройств. Допустимо, чтобы они занимали 25K плюс 64K, используемых Бейсиком. В системах с 64K используйте при старте команду CLEAR, которая ограничивает объем памяти доступный для Бейсика. CLEAR,n ограничивает Бейсик n байтами. Затем помес- тите процедуру в самые верхние адреса памяти. Для указания начала области, куда будет помещена процедура, используйте оператор DEF SEG, а затем с помощью оператора READ считываются байты процедуры и помещаются в память до тех пор, пока вся процедура не будет помещена на место. Например: 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. Например: 500 DEF SEG = &H3000 'указываем на начало процедуры 510 DOGS = 12 'у нее 3 параметра 520 CATS = 44 ' 530 POSSUMS = 1 ' 540 CASUALTIES = 0 'начинаем выполнение с 1-го байта 550 CALL CASUALTIES(DOGS,CATS,POSSUMS) 'выполняем процедуру Имеется намного более простой и экономичный способ создания ассемблерных процедур, который избегает проблемы распределения памяти. Надо просто создать процедуру в виде строковой переменной внутри программы. Каждый байт может быть закодирован с помощью CHR$. Затем используйте функцию VARPTR для определения положения этой строки в памяти. Смещение по которому находится эта перемен- ная хранится в двух байтах, которые идут за тем, на который ука- жет VARPTR (в первом байте содержится длина строки). Затем этот адрес используется для вызова процедуры. Отметим способ, которым используется оператор DEF SEG, для указания на сегмент данных Бейсика, с тем чтобы полученное смещение указывало на адрес стро- ки для оператора CALL. Например: 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). На самом деле боль- шинство символов ASCII могут вводиться путем нажатия клавиши Alt, наборе номера кода на дополнительной клавиатуре, а затем отпуска- ния клавиши Alt. Однако коды от 0 до 31 не могут быть введены таким образом для наших целей. Приложение Д. Использование драйвера устройства ANSI.SYS. ANSI.SYS это небольшая программа, входящая в состав операцион- ной системы, которая может быть загружена в память, с тем чтобы увеличить возможности MS DOS. Она не сделана частью COMMAND.COM с целью экономия памяти, когда она не используется. Средства, пре- доставляемые ANSI.SYS, могут быть использованы для удобства прог- раммирования, но они могут также служить средством достижения некоторой программной совместимости с не IBM-овскими машинами, использующими MS DOS. Этот драйвер не предоставляет никаких доба- вочных возможностей, которых нельзя было бы добиться другим обра- зом, но он делает некоторые возможности управления клавиатурой и терминалом намного более простыми (и обычно более медленно). Все свойства драйвера ANSI.SYS описаны в этой книге под соответствую- щим заголовком. ANSI.SYS может быть загружен только во время загрузки опера- ционной системы. Начиная с версии 2.0 система автоматически ищет файл CONFIG.SYS, так же как и файл AUTOEXEC.BAT. Файл CONFIG.SYS содержит различные параметры, такие как число создаваемых буферов для файлов. Но он содержит также и имена тех драйверов устройств, которые должны быть загружены и включены в COMMAND.COM. ANSI.SYS как раз и является таким драйвером. Надо просто включить в этот файл строку DEVICE = ANSI.SYS. Она может быть единственной стро- кой в файле. Для создания этого файла можно воспользоваться ко- мандой COPY. Надо просто ввести с терминала такие строки: COPY CON: CONFIG.SYS <CR> DEVICE = ANSI.SYS <CR> <F6> <CR> Нажатие клавиши F6 записывает символ Ctrl-Z (ASCII 26), отмечаю- щий конец файла. Приложение Е. Набор инструкций микропроцессора 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 Необходимо добавить также 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 LODS (REP) строка-источник 9+13(17)/повтор 1 LOOP короткая метка 17 или 5 2 LOOPE короткая метка 18 или 6 2 LOOPNE короткая метка 19 или 5 2 LOOPNZ короткая метка 19 или 5 2 LOOPZ короткая метка 18 или 6 2 MOV память, аккумулятор 10(14) 3 MOV аккумулятор, память 10(14) 3 MOV регистр, регистр 2 2 MOV регистр, память 8(12) + EA 2-4 MOV память, регистр 9(13) + EA 2-4 MOV регистр, значение 4 2-3 MOV значение, регистр 10(14) + EA 3 MOV сегментный регистр, словный регистр 2 2 MOV сегментный регистр, слово памяти 8(12) + EA 2-4 MOV словный регистр, сегментный регистр 2 2 MOV слово памяти, сегментный регистр 9(13) + EA 2-4 MOVS приемник, источник 18(26) 1 MOVS (REP) приемник, источник 9+17(25)/повтор 1 MUL байтный регистр 70-77 2 MUL словный регистр 118-133 2 MUL байт памяти (76-83) + EA 2-4 MUL слово памяти (128-143) + EA 2-4 NEG регистр 3 2 NEG память 16(24) + EA 2-4 NOP 3 1 NOT регистр 3 2 NOT память 16(24) + EA 2-4 OR регистр, регистр 3 2 OR регистр, память 9(13) + EA 2-4 OR память, регистр 16(24) + EA 2-4 OR регистр, значение 4 3-4 OR память, значение 17(25) + EA 3-6 OR аккумулятор, значение 4 2-3 OUT байт значения, аккумулятор 10(14) 2 OUT DX, аккумулятор 8(12) 1 POP регистр 12 1 POP сегментный регистр 12 1 POP память 25 + EA 2-4 POPF 12 1 PUSH регистр 15 1 PUSH сегментный регистр 14 1 PUSH память 24 + EA 2-4 PUSHF 14 1 RCL регистр, 1 2 2 RCL регистр, CL 8+4/бит 2 RCL память, 1 15(23) + EA 2 RCL память, 1 20(28)+EA+4/бит 2 RCR регистр, 1 2 2 RCR регистр, CL 8+4/бит 2 RCR память, 1 15(23) + EA 2 RCR память, 1 20(28)+EA+4/бит 2 REP 2 1 REPE 2 1 REPNE 2 1 REPZ 2 1 REPNZ 2 1 RET (внутрисегментный, без POP) 20 1 RET (внутрисегментный, с POP) 24 3 RET (межсегментный, без POP) 32 1 RET (межсегментный, с POP) 31 3 ROL регистр, 1 2 2 ROL регистр, CL 8+4/бит 2 ROL память, 1 15(23) + EA 2 ROL память, 1 20(28)+EA+4/бит 2 ROR регистр, 1 2 2 ROR регистр, CL 8+4/бит 2 ROR память, 1 15(23) + EA 2 ROR память, 1 20(28)+EA+4/бит 2 SAHF 4 1 SAL регистр, 1 2 2 SAL регистр, CL 8+4/бит 2 SAL память, 1 15(23) + EA 2 SAL память, 1 20(28)+EA+4/бит 2 SAR регистр, 1 2 2 SAR регистр, CL 8+4/бит 2 SAR память, 1 15(23) + EA 2 SAR память, 1 20(28)+EA+4/бит 2 SBB регистр, регистр 3 2 SBB регистр, память 9(13) + EA 2-4 SBB память, регистр 16(24) + EA 2-4 SBB регистр, значение 4 3-4 SBB память, значение 17(25) + EA 3-6 SBB аккумулятор, значение 4 2-3 SCAS приемник 15(19) 1 SCAS (REP) приемник 9+15(19)/повтор 1 SHL регистр, 1 2 2 SHL регистр, CL 8+4/бит 2 SHL память, 1 15(23) + EA 2 SHL память, 1 20(28)+EA+4/бит 2 SHR регистр, 1 2 2 SHR регистр, CL 8+4/бит 2 SHR память, 1 15(23) + EA 2 SHR память, 1 20(28)+EA+4/бит 2 STC 2 1 STD 2 1 STI 2 1 STOS приемник 11(15) 1 STOS (REP) приемник 9+10(14)/повтор 1 SUB регистр, регистр 3 2 SUB регистр, память 9(13) + EA 2-4 SUB память, регистр 16(24) + EA 2-4 SUB регистр, значение 4 3-4 SUB память, значение 17(25) + EA 3-6 SUB AL, значение 4 2-3 TEST регистр, регистр 3 2 TEST регистр, память 9(13) + EA 2-4 TEST регистр, значение 5 3-4 TEST память, значение 11 + EA 3-6 TEST AL, значение 4 2-3 WAIT 3 + 5n 1 XCNG AL, словный регистр 3 1 XCNG память, регистр 17(25) + EA 2-4 XCNG регистр, регистр 4 2 XLAT таблица-источник 11 1 XOR регистр, регистр 3 2 XOR регистр, память 9(13) + EA 2-4 XOR память, регистр 16(24) + EA 2-4 XOR регистр, значение 4 3-4 XOR память, значение 17(25) + EA 3-6 XOR AL, значение 4 2-3 Приложение Ж. Набор инструкций микропроцессора 80286. Придерживаясь схемы, принятой в данной книге, здесь перечисле- ны инструкции только для режимов реальной адресации. Более мощный микропроцессор 80286 не требует добавочного времени на вычисление эффективных адресов, нет также отличия в выполнении команд над байтными и словными переменными. Звездочка указывает, что Вы должны добавить один такт, если при вычислении смещения сумми- руются три элемента. Буква m указывает число байтов следующей инструкции, а n - число повторений. такты байты AAA 3 1 AAD 14 2 AAM 16 2 AAS 3 1 ADC регистр/память с регистром 2,7* 2 ADC значение с регистром/памятью 3,7* 3-4 ADC значение с аккумулятором 3 2-3 ADD регистр/память с регистром 2,7* 2 ADD значение с регистром/памятью 3,7* 3-4 ADD значение с аккумулятором 3 2-3 AND регистр/память с регистром 2,7* 2 AND значение с регистром/памятью 3,7* 3-4 AND значение с аккумулятором 3 2-3 CALL прямой внутри сегмента 7+m 3 CALL косвенный через регистр/память внутри сег-та 7+m,11+m* 2 CALL прямой между сегмента 13+m 5 CBW 2 1 CLC 2 1 CLD 2 1 CLI 3 1 CMC 2 1 CMP регистр/память с регистром 2,6* 2 CMP регистр с регистром/памятью 2,7* 2 CMP значение с регистром/памятью 3,6* 3-4 CMP значение с аккумулятором 3 2-3 CMPS повторенный CX раз 5 + 9n 2 CMPS байт или слово 8 1 CWD 2 1 DAA 3 1 DAS 3 1 DEC регистр/память 2,7* 2 DEC регистр 2 1 DIV байтный регистр 14 2 DIV словный регистр 22 2 DIV байт памяти 17* 2 DIV слово памяти 25* 2 ESC 9-20* 2 HLT 2 1 IDIV байтный регистр 17 2 IDIV словный регистр 25 2 IDIV байт памяти 20* 2 IDIV слово памяти 28* 2 IMUL байтный регистр 13 2 IMUL словный регистр 21 2 IMUL байт памяти 16* 2 IMUL слово памяти 24* 2 IMUL умножение на целое значение 21,24* 3-4 IN фиксированный порт 5 2 IN переменный порт 5 1 INC регистр/память 2,7* 2 INC регистр 2 1 INS строка 5 + 4m 2 INS байт или слово 5 1 INT указанный тип 23 + m 2 INT тип 3 23 + m 1 INTO 24 + m или 3 1 IRET 17 + m 1 JCXZ 8 + m или 4 2 JMP короткий/длинный 7 + m 2 JMP прямой внутри сегмента 7 + m 2 JMP косвенный через регистр/память 7 + m,11 + m* 2 JMP прямой между сегментами 7 + m 2 Jxxx 7 + m или 3 2 LAHF 2 1 LDS 7* 2 LEA 3* 2 LES 7* 2 LOCK 0 1 LODS 5 1 LODS повторенный CX раз 5 + 4n 1 LOOP 8 + 4n или 4 2 LOOPZ/LOOPE 8 + 4n или 4 2 LOOPNZ/LOOPNE 8 + 4n или 4 2 MOV регистр в регистр/память 2,3* 2 MOV регистр/память в регистр 2,5* 2 MOV значение в регистр/память 2,3* 3-4 MOV значение в регистр 2 2-3 MOV память в аккумулятор 5 3 MOV аккумулятор в память 3 3 MOV регистр/память в сегментный регистр 2,5* 2 MOV сегментный регистр в регистр/память 2,3* 2 MOVS байт или слово 5 1 MOVS повторенное CX раз 5 + 4n 2 MUL байтный регистр 13 2 MUL словный регистр 21 2 MUL байт памяти 16* 2 MUL слово памяти 24* 2 NEG 2 2 NOT регистр/память 2,7* 2 OR регистр/память с регистром 2,7* 2 OR значение с регистром/памятью 3,7* 3-4 OR значение с аккумулятором 3 2-3 OUT фиксированный порт 3 2 OUT переменный порт 3 1 OUTS строка 5 + 4m 2 OUTS байт или слово 5 1 POP память 5* 2 POP регистр 5 1 POP сегментный регистр 5 1 POPA 19 1 POPF 5 1 PUSH память 5* 2 PUSH регистр 3 1 PUSH сегментный регистр 3 1 PUSH значение 3 2-3 PUSHA 17 1 PUSHF 3 1 RCA регистр/память на 1 2,7* 2 RCA регистр/память на CX 5+n, 8+n* 2 RCA регистр/память на число 5+n, 8+n* 3 RCR регистр/память на 1 2,7* 2 RCR регистр/память на CX 5+n, 8+n* 2 RCR регистр/память на число 5+n, 8+n* 3 RET внутри сегмента 11 + m 1 RET внутри сегмента, добавляя значение к SP 11 + m 3 RET между сегментами 15 + m 1 RET между сегментами, добавляя значенме к SP 15 + m 3 ROL регистр/память на 1 2,7* 2 ROL регистр/память на CX 5+n, 8+n* 2 ROL регистр/память на число 5+n, 8+n* 3 ROR регистр/память на 1 2,7* 2 ROR регистр/память на CX 5+n, 8+n* 2 ROR регистр/память на число 5+n, 8+n* 3 SAHF 2 1 SAL регистр/память на 1 2,7* 2 SAL регистр/память на CX 5+n, 8+n* 2 SAL регистр/память на число 5+n, 8+n* 3 SAR регистр/память на 1 2,7* 2 SAR регистр/память на CX 5+n, 8+n* 2 SAR регистр/память на число 5+n, 8+n* 3 SBB регистр/память с регистром 2,7* 2 SBB значение с регистром/памятью 3,7* 3-4 SBB значение с аккумулятором 3 2-3 SCAS повторенное CX раз 5+8n 2 SCAS байт или слово 7 1 SEG (переопределение сегмента) 0 1 SHL регистр/память на 1 2,7* 2 SHL регистр/память на CX 5+n, 8+n* 2 SHL регистр/память на число 5+n, 8+n* 3 STC 2 1 STD 2 1 STI 2 1 STOS повторенное CX раз 5+3n 2 STOS 3 1 SAL регистр/память на 1 2,7* 2 SAL регистр/память на CX 5+n, 8+n* 2 SAL регистр/память на число 5+n, 8+n* 3 SUB регистр/память с регистром 2,7* 2 SUB значение с регистром/памятью 3,7* 3-4 SUB значение с аккумулятором 3 2-3 TEST регистр/память с регистром 2,6* 2 TEST значение с регистром/памятью 3,6* 3-4 TEST значение с аккумулятором 3 2-3 WAIT 3 1 XCNG регистр/память с регистром 3,5* 2 XCNG регистр с аккумулятором 3 1 XLAT 5 1 XOR регистр/память с регистром 2,7* 2 XOR значение с регистром/памятью 3,7* 3-4 XOR значение с аккумулятором 3 2-3 Приложение З. Толковый словарь IBM PC. 146818: Микросхема в AT, содержащая часы реального времени и информацию о конфигурации. 6845: Микросхема контроллера дисплея. 76496: Микросхема синтезатора звука PCjr. 765 (PD765): Микросхема контроллера НГМД. 8048: Микропроцессор клавиатуры. 8237: Микросхема прямого доступа к памяти (DMA). 8250: Микросхема коммуникационного адаптера. 8253: Микросхема программируемого таймера. 8255: Микросхема адаптера интерфейса с периферией. 8259: Микросхема контроллера прерываний. 8087: Микросхема математического сопроцессора на PC, XT и PCjr. 8088: Центральный процессор у PC, XT и PCjr. 80286: Центральный процессор у AT. 80287: Микросхема математического сопроцессора на AT. Абсолютный адрес: Адрес памяти, выраженный в виде смещения отно- сительно младшего адреса (0000:0000), а не относительно како- го-либо определенного смещения в памяти (относительный адрес). Абсолютные координаты: Координаты, указанные относительно цент- ральной оси, а не относительно предыдущих используемых координат (относительные координаты). Абсолютные сектора диска: Под "доступом к абсолютному сектору диска" понимается чтение сектора, занимающего определенное поло- жение на диске. Код доступа: Этот термин используется в Техническом руководстве по MS DOS для номера подфункции - т.е. для кода одной из несколь- ких функций, которые могут выполняться данным прерыванием. Подтверждение: Сигнал ввода/вывода, индицирующий, что задача выполнена и оборудование снова готово начать выполнение задачи. Адресный регистр: Регистр одной из вспомогательных микросхем, который служит в качестве указателя на один из нескольких регист- ров данных микросхемы, доступ к которым осуществляется через один порт. Программа должна сначала индексировать регистр, посылая номер интересующего регистра в адресный регистр. Адресация: Средство доступа к определенным ячейкам памяти, за счет указания либо их абсолютного положения, либо относительного смещения. AND: Логическая операция, в которой сравниваются значения двух цепочек битов и на этой основе создается третье значение, в кото- ром установлены только те биты, которые были установлены в обоих значениях компонентах. ANSI.SYS: Драйвер устройства, поставляемый вместе с операционной системой, который способен выполнять многие функции BIOS. Он используется для достижения программной совместимости с машинами, использующими MS DOS, отличными от IBM PC. Коды ASCII: Набор кодов от 0 до 127, соответствующих одному из 128 символов ASCII. IBM PC использует расширенный набор кодов ASCII, состоящий из 256 символов. Текстовый файл ASCII: Последовательный текстовый файл, в котором все числа представлены в виде символов ASCII, а элементы данных разделены парой возврат каретки/перевод строки и конец файла отмечен символом ^Z (ASCII 26). Строка ASCIIZ: То же, что и строка пути. Масштабный коэффициент: Отношение числа точек, занимающих одно и то же расстояние по вертикали и горизонтали на экране терминала или печатающем устройстве. Ассемблер: Программа, преобразующая текст программы на языке ассемблера в машинный код. Яэык ассемблера: Язык программирования самого низкого уровня, в котором программист пишет инструкции непосредственно управляющие работой процессора. Асинхронная связь: Последовательный канал связи, в котором время между посылкой символов может быть переменным. Атрибут: Характеристика, приписываемая устройству или данным. Каждый символ текстового экрана имеет атрибуты, определяющие его цвет, интенсивность и т.д. Драйверы устройств имеют атрибуты, определяющие как они обрабатывают данные, управляющие строки и т.д. Файлы могут иметь атрибуты, указывающие, что они являются скрытыми, только для чтения и т.д. Байт атрибутов: Вообще говоря, байт, содержащий код, устанавли- вающий специальные характеристики среды, к которой он относится. Байт атрибутов файла (в дисковом каталоге) определяет статус скрытого файла, статус только для чтения и т.п. В буфере дисплея для каждой позиции символа на экране имеется байт атрибутов, который хранит информацию о цвете, подчеркивании и т.д. AUTOEXEC.BAT: Имя командного файла, который автоматически выпол- няется при загрузке системы. B: Суффикс, обозначающий число, представленное в двоичном виде, например, 10111011B. См. приложение А. Фоновый цвет: Фоновый цвет используется дисплеем. Это тот цвет, который принимает весь экран, когда он очищен. Фоновые операции: Вторичный процесс, выполняемый при выполнении программы. Например, текстовый редактор может посылать данные на принтер в то время, когда программа используется для редактирова- ния. Фоновые операции могут работать за счет использования преры- ваний. Базовый адрес: Младший из группы смежных адресов портов, через которые осуществляется доступ к периферийному устройству. Командный файл: Файл, содержащий список команд и программ DOS, которые будут автоматически вызываться в том порядке, в котором они записаны, либо порядок их выполнения может определяться ус- ловными операторами. Скорость обмена: Число битов в секунду, которое передается при обмене. BIOS: Базовая система ввода/вывода, котораяявляется частью опе- рационной системы, постоянно хранящейся в ПЗУ машины. Область данных BIOS: Область данных, начинающаяся с адреса 0040:0000, в которой BIOS хранит статусную информацию и буфер клавиатуры. Битовое поле: Когда байт или слово рассматриваются как цепочка битов, то некоторые биты, взятые вместе, могут хранить определен- ный элемент информации. Например, биты 0-3 байта атрибутов симво- ла на дисплее оьразуют битовое поле, которое определяет основной цвет символа. Битовые операции: Программные операции, читающие или изменяющие определенные биты данных. Битовая плоскость: В EGA видеобуфер разделен на четыре области, которые называются битовыми плоскостями 0-3. В режиме 16-ти цве- тов четыре плоскости параллельны, при этом 4 байта, относятся к определенному адресу памяти (регистры задвижки определяют обмен данными между процессором и памятью дисплея). В некоторых случаях плоскости могут быть связаны в цепь, образуя одну или две большие плоскости. Блочные устройства: Устройства, которые посылают и принимают данные порциями в блок. Дисковые накопители являются наиболее обычными блочными устройствами. Запись начальной загрузки: Короткая программа, которая помещает- ся на диск в такой позиции, которая считывается с диска в первую очередь при загрузке системы. Эта программа дает компьютеру воз- можность загрузить части операционной системы. Граница: Определенный интервал в памяти, в файле и т.д. Напри- мер, программы размещаются в памяти, выравненными на 16-байтную границу. Это означает, что абсолютные адреса этих ячеек должно точно делиться на 16. Код отпускания: Тип скан-кода, который генерируется при отпуска- нии клавиши (код нажатия генерируется при нажатии клавиши). Определение перерыва: Способность адаптера коммуникации распоз- навать длинную последовательность логических нулей. Это сигнали- зирует о том, что отдаленная станция хочет перерыва в связи. Буфер: Область памяти, отводимая для хранения данных, которые будут передаваться от одной части компьютера к другой. БУфер используется клавиатурой, то же самое относится и к дисковым накопителям и дисплею. Флаг переноса: Один из битов регистра флагов процессора, который часто используется функциями MS DOS для индикации ошибки. CD: "Носитель обнаружен". См. DCD. Связь в цепочку: У EGA видеопамять разделена на 4 битовые плос- кости. Когда они объединяются в одну или две большие плоскости, то это называется связью в цепочку. Символьное устройство: Устройство, которое посылает или прини- мает данные по одному символу, такие как принтер. Сравните с блочными устройствами, которые обмениваются данными блоками. Процесс потомок: Программа, запускаемая когда другая программа (родитель) имеет управление. Циклическая очередь: Тип буфера данных, в котором данные встав- ляются с одного конца, а берутся с другого. Текущие положения этих двух концов постоянно меняются и два указателя хранят теку- щие положения "головы" и "хвоста". Кластер: Группа дисковых секторов, образующая основную единицу, которая используется при распределении дискового пространства. Код: Набор выполняемых инструкций, составляющих программу, в отличие от данных, над которыми выполняются операции. Вообще говоря, кодом называется последовательность машинных инструкций, которые производит транслятор или ассемблер из текста программы. Кодовый сегмент: Область памяти, хранящая программный код (дру- гие сегменты хранят данные и стек). Атрибуты цвета: Цепочки битов, хранимые в видеобуфере, которые определяют цвет определенной точки или символа на экране. Для монохромного и цветного адаптера эти атрибуты совпадают с систе- мой кодовых номеров цвета. Однако для PCjr и EGA относятся к номеру регистра палетты, а уже этот регистр содержит код цвета, с которым связан этот атрибут. Код цвета: Число от 0 до 15, которое относится к одному из шест- надцати цветов дисплея. Для дисплея EGA, присоединенному к улуч- шенному графичекому адаптеру, могут быть 64 кода цвета (0-63). COM: Тип исполняемого файла, в котором привязка уже выполнена и поэтому все адреса уже правильно записаны в файле перед его заг- рузкой. Командная строка: Строка на экране дисплея, принимающая управ- ляющую информацию, такая как строка, начинающаяся с запроса опе- рационной системы. Коммуникационное прерывание: Аппаратное прерывание, вызываемое адаптером асинхронной связи. Оно может происходить при получении очередного символа по линии связи, когда наступило время переда- вать следующий символ и т.п. Компилятор: Программа, преобразующая текст программы на языке высокого уровня в файл, содержащий исполняемый машинный код (или, иногда в промежуточный код, который затем исполняется интерпрета- тором). CONFIG.SYS: Имя специального файла, который система просматри- вает при загрузке. Этот файл содержит информацию о параметрах системы и драйверах устройств, которые должны быть установлены, что позволяет установить требуемую конфигурацию системы. Управляющий блок: См. блок параметров. Управляющий код: Один из первых 32 символов набора кодов ASCII. Они обычно используются управления оборудованием, а не кодирова- ния данных. Наиболее часто употреблямыми управляющими кодами являются возврат каретки и перевод строки. Управляющая строка: Строка символов, управляющая оборудованием. Управляющие строки часто включаются в поток данных, посылаемых на принтер или модем. Они начинаются со специального символа, указывающего их специальный статус (обычно, символ ESC, ASCII 27). CPU: Центральный процессор, который выполняет инструкции, сос- тавляющие компьютерную программу. У всех IBM PC центральным про- цессором является микросхема 8088, за исключением PC AT, у кото- рого процессором служит микросхема 80286. CRC: См. циклический контроль четности. Критическая ошибка: Ошибка устройства, которая делает дальнейшее выполнение программы невозможным. При этом вызывается обработчик критических ошибок операционной системы. Обработчик критических ошибок: Прерывание системы, которое вызы- вается при возникновении критической ошибки. Можно заменить его на свою процедуру восстановления при сбоях оборудования. CR/LF: Возврат каретки/перевод строки. Эта пара символов исполь- зуется, чтобы вызвать перевод курсора или печатающей головки к началу следующей строки. CRT: Электронно-лучевая трубка, т.е. видеодисплей. CTS: Очистка посылки. Сигнал от модема порту коммуникации, инди- цирующий, что модем готов начать передачу данных. Он является частью процедуры установления связи. Текущий блок: Блок данных файла, состоящий из 128 записей, на который ссылаеися при доступе к файлу методом управляющего блока файла. См. текущий номер записи. Текущий каталог: Каталог, являющийся частью дерева каталогов, к которому автоматически адресуются все файловые операции, до тех пор, пока строка пути в спецификации файла не указывает другого. Текущий номер записи: При доступе к файлам методом управляющего блока файла, данные организованы в блоки по 128 записей. Текущий номер записи это номер записи в текущем блоке. Например, текущий номер записи для записи прямого доступа номер 128 будет равен 0, поскольку она будет первой записью в блоке 1 (весь отсчет начи- нается с нуля, поэтому запись с номером 128 будет 129-й записью файла, блок 1 - вторым блоком, а последняя запись блока 0 имеет номер 127). Циклический контроль четности: Метод проверки ошибок, в котором за переданным блоком данных следует вычисленный математически результат; после приема вычисление повторяется и сравнивается с переданным, чтобы быть уверенным, что данные переданы без искаже- ния. Цилиндр: У дисковых накопителей цилиндром называется группа дорожек, находящихся на одинаковом расстоянии от центра диска или дисков, помещенных в накопитель. Сегмент данных: Область памяти, содержащая данные программы. В языке ассемблера на эту область указывает регистр DS. Область переноса данных: Буфер, используемый при доступе к фай- лам с помощью метода управляющего блока файла, который содержит данные передаваемые на диск или с диска. DB: Термин языка ассемблера, указывающий, что объект данных имеет размер 1 байт, или что это строка состаящая из однобайтовых кодов. DCD: Обнаружен носитель данных. Сигнал от модема порту коммуни- кации, индицирующий, что установлена связь с другим модемом. DD: Термин языка ассемблера, индицирующий, что объект данных имеет длину 4 байта. DTA по умолчанию: Область переноса данных, размером 128 байтов, которая выделяется каждой программе и начинается со смещения 80H в префиксе программного сегмента. Ограничитель: Специальный символ, разделяющий элементы данных. Устройство: Вообще говоря, устройством называется любое оборудо- вание, которое хранит, выводит или обрабатывает информацию, такое как дисковый накопитель, видеодисплей или принтер. Драйвер устройства: Программная процедура, управляющая устрйст- вом, таким как дисковый накопитель или принтер. Заголовок устройства: Начальная часть процедуры драйвера уст- ройства, которая идентифицирует устройство. Обработчик прерывания устройства: Основная часть процедуры драй- вера устройства; она содержит код, выполняющий основные функции драйвера. Стратегия устройства: Часть процедуры драйвера устройства, свя- зывающая драйвер с заголовком запроса, который является блоком параметров, который создает система для управления драйвером. Прямой доступ к памяти: Способ осуществления очень быстрого обмена между периферийным устройством и памятью. Он особенно полезен при дисковых операциях. Этот метод использует специальную микросхему (которая отсутствует у PCjr). Прямое отображение в память: См. отображение в память. DMA: См. прямой доступ к памяти. Запрос системы: Символы, появляющиеся в начале командной строки, например, A> или B>. Указатель накопителя: Двухбайтная строка, именующая дисковый накопитель, в виде A:, B: и т.д. DSR: Готовность набора данных. Сигнал коммуникационному порту от модема, индицирующий, что модем готов. DTA: Область обмена с диском. Буфер, используемый при обмене с диском, при использовании метода доступа управляющего блока фай- ла. DTR: Приемник данных готов. Сигнал от коммуникационного порта к модему, индицирующий, что компьютер готов. DW: Термин языка ассемблера, указывающий, что объект данных имеет длину 2 байта. Эхо: Возврат для проверки. Например, при вводе с клавиатуры обычно выдается эхо на экран, выдается эхо и при выводе через коммуникационный канал. Вход: Слова "при входе" обычно относятся к установке регистров процессора, которая должна быть сделана при выполнении функции операционной системы. Строка окружения: Строка, состоящая из одной или более спрецифи- каций, которым система следует при выполнении программы. Она может содержать конфигурационные команды, вводимые пользователем, такие как BUFFERS или BREAK. EOF: Сокращение для "конца файла". Код ошибки: Кодовый номер, выдываемый операционной системой для индикации определенного ошибочного условия. Обработка ошибок: Код, позволяющий программе передать управление специальной процедуре восстановления при сбоях при возникновении критической ошибки. Esc-последовательность: Управляющая строка, начинающаяся с сим- вола Esc (ASCII 27). Например, большинство управляющих команд принтера выполняется с помощью Esc-последовательностей. EXE: Исполняемый файл, который требует привязки при загрузке. Не все адреса программы могут быть установлены до тех пор, пока неизвестно ее положение в памяти. EXE-файлы имеют заголовок, который содержит информацию об этой привязке. Эти файлы загру- жаются немного дольше и требуют больше места на диске, чем файлы типа COM. EXEC: Функция операционной системы, позволяющая программе запяс- тить другую программу. Она может также загружать оверлеи. Код завершения: Код передаваемый процессом потомком процессу родителю. Например, когда когда одна программа запускает другую, то код завершения может быть передан от потомка родителю при завершении задачи потомка. Эти коды могут определяться програм- мистом. Расширенный код: Код клавиши, используемый для идентификации нажатия этой клавиши (или комбинации клавиш), для которой нет соответствующего символа в наборе ASCII, такой как функциональные клавиши или комбинации с клавишами Ctrl или Alt. Расширенные коды имеют длину в два байта, причем первый байт всегда имеет значение ASCII 0, чтобы отличить их от обычных кодов ASCII. Расширенный код ошибки: Начиная с версии 3.0 MS DOS более под- робные расширенные коды ошибки возвращаются при возникновении ошибки. Эти коды сообщают не только об ошибке, но и об ее типе, ее месте в оборудовании и возможных способах восстановления. Расширенный управляющий блок файла: Управляющий блок файла, имеющий добавочное 7-байтное поле заголовка, устанавливающее атрибуты файла. Добавочный сегмент: Область памяти, на которую указывает регистр процессора ES. Установка ES и DS (регистр сегмента данных) часто используется совместно для переноса данных из одной части памяти в другую. FAT: См. таблица размещения файлов. FCB: См. управляющий блок файла. Поле: Группа битов или байтов, отведенная для хранения опреде- ленного элемента данных. Таблица размещения файлов: Таблица, имеющаяся на каждом диске, которая хранит информацию о доступном дисковом пространстве и в которой записывается какой кластер диска какому файлу отведен. Атрибуты файла: Поле элемента каталога файлов, определ