ние размера свободного дискового пространства: шест.36 Данная функция выдает информацию о дисковой памяти. Для выполнения функции необходимо загрузить в регистр DL номер дисковода (0 - текущий дисковод, 1 - A, 2 - B и т.д.): MOV AH,36H ; Запрос на MOV DL,0 ; текущий дисковод INT 21H ; Вызов DOS При указании неправильного номера дисковода операция воз вращает в регистре AX шест.FFFF, иначе следующие значения: в AX число секторов на кластер в BX число доступных кластеров в CX число байтов на сектор в DX общее число кластеров на дисководе В версии DOS младше 2.0 для получения информации о диско вой памяти следует использовать функцию шест.1B (получить информацию из табблицы FAT). Удаление файла: шест.41 Для удаления файлов из программы (за исключением файлов с атрибутом "только чтение") используется функция шест.41. При этом в регистре DX необходимо загрузить ASCIIZ строку, содержащую путь доступа и имя файла: MOV AH,41H ; Запрос на удаление LEA DX,PATHNAM ; ASCIIZ-строка INT 21H ; Вызов DOS В случае ошибки в регистре AX возвращается код 02 (файл не найден) или 05 (нет доступа). Управление файловым указателем: шест.42 Система DOS имеет файловый указатель, который при открытии файла устанавливается в 0 и увеличивается на 1 при последовательных операциях записи или считывания. Для доступа к любым записям внутри файла можно менять файловый указатель с помощью функции шест.42, получая в результате прямой доступ к записям файла. Для установки файлового указателя необходимо поместить в регистр BX файловый номер и в регистровую пару CX:DX требуе мое смещение в байтах. Для смещений до 65.535 в регистре CX устанавливается 0, а в DX - смещение. В регистре AL должен быть установлен один из кодов, который определяет точку отсчета смещения: 0 - смещение от начала файла. Ассемблер для IBM PC. Глава 17. 9 1 - смещение текущего значения файлового указателя, которое может быть в любом месте, включая начало файла. 2 - смещение от конца файла. Размер файла (и следовательно смещение до конца файла) можно определить, установив регистровую пару CX:DX в 0 и используя код 2 в регистре AL. В следующем примере устанавливается файловый указатель на смещение 1024 байта от начала файла: MOV AH,42H ; Установка указателя MOV AL,00 ; от начала файла LEA BX,HANDLE1 ; Установка файлового номера MOV CX,00 ; MOV DX,1024 ; Смещение 1024 байта INT 21H ; Вызов DOS JC error Правильно выполненная операция сбрасывает флаг CF и воз вращает новый указатель в регистровой паре DX:AX. Неправиль ная операция устанавливает флаг CF в 1 и возвращает в регист ре AX код 01 (ошибка кода отсчета) или 06 (ошибка файлового номера). Проверка или изменение атрибута: шест.43 Для проверки или изменения файлового атрибута в оглавле нии диска используется функция шест.43H. При этом в регистре DX должен быть установлен адрес ASCIIZ строки. Для проверки атрибута регистр AL должен содержать 00. Для изменения атрибута регистр AL должен содержать 01, а регистр CX - новое значение атрибута. Следующий пример устанавливает нормальный атрибут: MOV AH,43H ; Запрос на установку MOV AL,01 ; нормального MOV CX,00 ; атрибута LEA DX,PATHNM2 ; ASCIIZ-строка INT 21H ; Вызов DOS В случае проверки функция возвращает текущий атрибут фай ла в регистре CX. В случае изменения функция устанавливает в соответствующем элементе оглавления атрибут из регистра CX. Неправильная операция возвращает в регистре AX коды ошибок 02, 03 или 05. Получить текущее оглавление: шест.47 Определение текущего оглавления для любого дисковода осуществляется с помощью функции шест.47. При этом необходи мо определить область памяти достаточно большую, чтобы содер жать пути доступа максимальной длины и загрузить адрес этой области в регистр DX. Регистр DL должен содержать номер дисковода: 0 - текущий, 1 - A, 2 - B и т.д. В результате Ассемблер для IBM PC. Глава 17. 10 выполнения операция помещает в область памяти имя текущей директории (без номера дисковода), например, в следующем виде: ASSEMBLE\EXAMPLES Нулевой байт (шест.00) идентифицирует конец составного имени пути доступа. Для корневой директории возвращаемое значение состоит только из одного байта - шест.00. Таким образом можно получить текущее имя пути доступа для любого файла в подоглавлении. Пример на рис.17.5 демонстрирует использование данной функции. Поиск файлов по шаблону: шест.4E и шест.4F Данные функции аналогичны функциям шест. 11 и 12 базовой версии DOS. Функция 4E используется для начала поиска в ог лавлении, а функция 4F - для продолжения. Для начала поиска в регистр DX необходимо загрузить адрес ASCIIZ-строки, содер жащей имя пути доступа и шаблон поиска. Шаблон поиска может включать в себя символы ? и *. В регистре CX должно быть значение атрибута в любой комбинации битов (нормальный, оглавление, спрятанный или системный). MOV AH,4EH ; Запрос на начало поиска MOV CX,00H ; Нормальный атрибут LEA DX,PATHNM1 ; ASCIIZ-строка INT 21H ; Вызов DOS Если операция находит файл, удовлетворяющий шаблону поиска, то в текущий буфер DTA в FCB заполняется следующей информацией: 00 - резервировано DOS для последующего поиска 21 - атрибут файла 22 - время файла 24 - дата файла 26 - размер файла: младшее слово, затем старшее слово 30 - имя и тип в виде 13-байтовой ASCIIZ строки, завершаемой шест.00. В случае ошибки в регистре AX возвращается код 02 (не найдено) или 18 (нет больше файлов). Для продолжения поиска файлов (после функции шест.4E) используется функция 4F. Между этими функциями не следует нарушать содержимое DTA. MOV AH,4FH ; Запрос на продолжение поиска INT 21H ; Вызов DOS Единственно возможный код в регистре AX - 18 (нет больше файлов). Обе рассмотренные функции не меняют состояние флага CF. Переименование файла: шест. 56 Ассемблер для IBM PC. Глава 17. 11 Для переименования файла используется функция шест.56. При этом в регистр DX должен быть загружен адрес ASCIIZ- строки, содержащей старые значения дисковода, пути доступа, имени и типа файла, а в регистр DI (в действительности ES:DI) - адрес ASCIIZ-строки, содержащей новые значения дисковода, пути доступа, имени и типа файла. Если указыва ется номер дисковода, то он должен быть одинаков в обоих строках. Путь доступа может быть различным, поэтому данная операция может не только переименовывать файл, но и перено сить его в другое подоглавление. MOV AH,56H ;Запрос на переименование файла LEA DX,oldstring ; DS:DX LEA DI,newstring ; ES:DI INT 21H ; Вызов DOS В случае ошибки регистр AX возвращает коды 03 (путь досту па не найден), 05 (нет доступа?) и 17 (разные дисководы). Другие функции DOS, имеющие отношение к дисковым файлам, включают создание подоглавления (шест.39), удаление элемента оглавления (шест.3A), изменение текущего оглавления (шест. 3B), управление вводом-выводом для устройств (шест.44), дублирование файлового номера (шест.45), принудительное дублирование файлового номера (шест.46), получение состояния проверки ? (шест.54). ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ - Многие функции расширенной версии DOS оперируют с ASCIIZ- строками, которые содержат путь доступа и завершаются байтом, содержащим шест.00. - Функции создания и открытия возвращают значение файлового номера, который используется для последующего доступа к файлу. - В случае ошибок многие функции устанавливают флаг CF и помещают код ошибки в регистр AX. - Как правило, функция создания используется для записи файла, а открытия - для чтения. - После того, как файл записан на диск, его необходимо закрыть для того, чтобы в оглавление были внесены соот ветствующие изменения. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 17.1. Какие значения кодов возврата для ситуаций "файл не найден" и "ошибка файлового номера" ? 17.2. Определите ASCIIZ-строку по имени PATH1 для файла CUST.LST на дисководе C. 17.3. Для предыдущего файла (п.17.2) напишите команды а) определения элемента по имени CUSTHAN для файлового номера, б) создание файла, в) записи файла из области CUSTOUT (128 байт) и г) закрытия файла. Обеспечьте проверку на ошибки. Ассемблер для IBM PC. Глава 17. 12 17.4. Для файла (п.17.3) напишите команды а) открытия файла и б) чтения файла в область CUSTIN. Обеспечьте конт роль ошибок. 17.5. В каких случаях необходимо закрывать файл, который был открыт только для чтения ? 17.6. Измените программу на рис.17.4 так, чтобы пользова тель мог вводить с клавиатуры имя файла, который необходимо выдать на экран. Обеспечьте возможность любого числа запросов и завершение программы только по пустому запросу, т.е. простому нажатию клавиши Return. Ассемблер для IBM PC. Глава 18. 1 ГЛАВА 18. Дисковая память IV: Функции BIOS ----------------------------------------------------------- Дисковая память IV: Функции BIOS Цель: Показать основные требования к программированию функций BIOS для создания и чтения дисковых файлов. ВВЕДЕНИЕ ----------------------------------------------------------- Для дисковых операций можно программировать непосред ственно на уровне BIOS, хотя BIOS и не обеспечивает автоматически использование оглавления или блокирование/ деблокирование записей. Дисковая операция BIOS INT 13H рас сматривает все "записи", как имеющие размер сектора, а адресацию диска осуществляет в терминах действительных номера дорожки и номера сектора. Для дисковых операций чтения, записи и верификации необ ходима инициализация следующих регистров: AH Определяет тип операции: чтение, запись, верификация или форматирование. AL Определяет число секторов. CH Определяет номер дорожки. CL Определяет номер начального сектора. DH Номер головки (стороны) : 0 или 1 для дискеты. DL Номер дисковода: 0=A, 1=B и т.д. ES:BX Адрес буфера ввода/вывода в области данных (за исключением операции верификации). ДИСКОВЫЕ ОПЕРАЦИИ В BIOS ----------------------------------------------------------- Для указания необходимой дисковой операции необходимо перед INT 13H загрузить в регистр AH соответствующий код. AH = 00: Сброс системы контролера дисковода Данная операция осуществляет полный сброс контролера дис ковода и требует для выполнения INT 13H загрузку в регистр AH значение шест.00. Операция используется в случаях, когда после других дисковых операций возвращается код серьезной ошибки. AH = 01: Определить состояние дисковода Данная операция возвращает в регистре AL состояние дисковода после последней операции вводда/вывода (см.Байт состояния в следующем разделе). Операция требует только загрузки значения 01 в регистр AH. AH = 02: Чтение секторов Данная операция выполняет чтение в память определенного числа секторов на одной дорожке. Число секторов обычно 1, 8 или 9. Адрес памяти для области ввода должен быть загружен в регистр BX, причем следует помнить, что реальный адрес Ассемблер для IBM PC. Глава 18. 2 зависит от содержимого регистра EX, так как в данном случае используется регистровая пара ES:BX. В следующем примере выполняется чтение сектора в область INSECT, которая должна быть достаточно большой, чтобы вместить все данные: MOV AH,02 ; Запрос на чтение MOV AL,01 ; один сектор LEA BX,INSERT ; Буфер ввода в ES:BX MOV CH,05 ; Дорожка 05 MOV CL,03 ; Сектор 03 MOV DH,00 ; Сторона (головка) 00 MOV DL,01 ; Дисковод 01 (B) INT 13H ; Вызов BIOS Число действительно прочитанных секторов возвращается в регистре AL. Регистры DS, BX, CX и DX сохраняют свои значения. В большинстве случаев программа указывает только один сектор или все сектора на дорожке. Для последовательного чтения секторов программа должна увеличивать содержимое регистров CH и CL. Заметьте, что когда номер сектора достигает максимального значения, его необходимо сбросить в 01, а номер дорожки увеличить на 1 или изменить сторону 0 на 1 (для двухсторонних дискет). AH = 03: Запись секторов Данная операция записывает данные из указанной области памяти (обычно 512 байтов или кратное 512) в один или несколько определенных секторов. Управляющая информация загружается в регистры аналогично операции чтения диска (код 02). Операция записи возвращает в регистре AL число секторов, которые действительно были записаны. Регистры DX, BX, CX и DX сохраняют свои значения. AH = 04: Верификация сектора Данная операция проверяет, может ли быть найден указанный сектор, и выполняет своего рода контроль на четность. Опера цию можно использовать после записи (код 03) для гарантии более надежного вывода, на что потребуется дополнительное время ввода/вывода. Значения регистров устанавливаются ана- логично операции записи (код 03), за исключением регистро- вой пары ES:BX - их инициализация не требуется. Операция возвращает в регистре AL число обработанных секторов. Ре- гистры DX, BX, CX и DX сохраняют свои значения. AH = 05: Форматирование дорожек Данная операция используется для форматирования опреде ленного числа дорожек в соответствии с одним из четырех размеров (стандарт для системы PC - 512). Операции чтения и записи для локализации требуемого сектора требуют информацию о формате. Для форматирования регистровая пара Ассемблер для IBM PC. Глава 18. 3 ES:BX должна содержать адрес, который указывает на группу адресных полей для дорожки. Для каждого сектора на дорожке должен быть четырехбайтовый элемент в виде T/H/S|B, где T номер дорожки, H номер головки, S номер сектора, B число байт на секторе, (00-128, 01-256, 02-512, 03-1024). Например, для форматирования 03 дорожки, на стороне 00 и 512 байтов на сектор, первый элемент должен иметь значение шест.03000102 и за ним должны быть описаны элементы для остальных секторов на дорожке. Техническое руководство по AT содержит ряд дополнительных операций BIOS. БАЙТ СОСТОЯНИЯ ------------------------------------------------------------ Для всех рассмотренных выше операций (02, 03, 04 и 05) в случае нормального завершения флаг CF и регистр AH содержит 0. В случае ошибки флаг CF устанавливается в 1, а регистр AH содержит код состояния, идентифицирующий причину ошибки. Код состояния аналогичен значению в регистре AL после выполнения операции 01. AH Причина 0000 0001 Ошибка команды для дискеты 0000 0010 Не найден адресный маркер на диске 0000 0011 Попытка записи на защищенный диск 0000 0100 Не найден сектор 0000 1000 Выход за границы DMA (памяти прямого доступа) 0000 1001 Попытка доступа через границу 64K 0001 0000 Чтение сбойный участок на диске 0010 0000 Ошибка контролера дисковода 0100 0000 Ошибка установки (поиска) 1000 0000 Ошибка оборудования В случае возникновения ошибки, обычным действием является сброс диска (AH=00) и троекратное повторение операции. Если таким образом ошибка не устраняется, то на экран выводится соответствующее сообщение и пользователь может сменить дискету. ПРОГРАММА: ИСПОЛЬЗОВАНИЕ BIOS ДЛЯ ЧТЕНИЯ СЕКТОРОВ ------------------------------------------------------------ Рассмотрим программу, приведенную на рис.18.1, в которой используется команда BIOS INT 13H для чтения секторов диска. Программа базируется на примере, приведенном на рис.16.3, со следующими изменениями: 1. Отсутствует описание FCB и подпрограмма открытия. Ассемблер для IBM PC. Глава 18. 4 2. Программа расчитывает каждый дисковый адрес. После каж дого чтения происходит увеличение номера сектора. При достижении номера сектора 10 процедура C10ADDR сбрасывает это значение в 01. Если номер стороны = 1, программа увеличивает номер дорожки; затем меняется номер стороны: 0 на 1 и 1 на 0. 3. Область CURADR содержит начальные значения номеров дорожки и сектора (их программа увеличивает), а область ENDADR - конечные значения. Один из способов улучшения программы - предоставить пользователю возможность указать начальные и конечные номера дорожки и сектора с помощью соответствующего запроса. Выполните данную программу под управлением отладчика DEBUG. Проделайте трассировку команд, которые инициализируют сегментные регистры, и установите начальный и конечный номера секторов для файловой таблицы FAT (расположение таблицы FAT различно в разных версиях операционной системы). Используя команду G (до) для выполнения ввода с диска и проверки считанного содержимого таблицы FAT и элементов оглавления. ------------------------------------------------------------ ------------------------------------------------------------ Рис.18.1. Использование BIOS для чтения дискового файла. В качестве альтернативы,отладчику DEBUG можно преобразо вать ASCII-символы в области ввода в их шест. эквиваленты и выдать на экран эти значения, как это делает отладчик DEBUG (см. программу на рис.14.5). Таким образом можно проверить содержимое любого сектора (в том числе "спрятанного"), а также предоставить пользователю возможность внести измене ния и записать измененный сектор на диск. Следует помнить, что при создании файла DOS может вносить записи на любые доступные сектора, которые не обязательно будут смежными на диске. Следовательно, с помощью команды BIOS INT 13H нельзя выполнить последовательное чтение файла. ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ - Команда BIOS INT 13 обеспечивает прямой доступ к дорожкам и секторам диска. - Команда BIOS INT 13 не поддерживает операции с оглавле нием, обнаружение конца файла, блокирование и деблокиро вание записей. - Верификация сектора выполняет элементарную проверку записанных данных, что приводит к увеличению времени обработки. - Проверяйте байт состояния после каждой дисковой операции через BIOS. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ Ассемблер для IBM PC. Глава 18. 5 18.1. Напишите команды для сброса дискового контролера. 18.2. Напишите команды для чтения байта состояния дискеты. 18.3. Напишите команды для BIOS INT 13H, выполняющие чтение одного сектора в область памяти INDISK, с дисковода A, головки 0, дорожки 6 и сектора 3. 18.4. Напишите команды для BIOS INT 13H, выполняющие запись трех секторов из области памяти OUTDISK, на дисковод B, головку 0, дорожку 8 и сектор 1. 18.5. При записи данных в вопросе 18.4, как можно распоз нать попытку записи на защищенный диск? 18.6. На основе вопроса 18.4 напишите команды контроля записи (операция верификации). Ассемблер для IBM PC. Глава 19 1 ГЛАВА 19. ПЕЧАТЬ ------------------------------------------------------------ ПЕЧАТЬ Цель: Описать возможности программ на языке ассемблера для вывода информации на печатающее устройство (принтер). ВВЕДЕНИЕ ------------------------------------------------------------ Вывод на принтер несколько проще операций с экраном и диском. Для печати существует несколько операций, выполняющихся через DOS INT 21H и BIOS INT 17H. Команды, посылаемые на принтер, включают коды "конец страницы", "конец строки" и "возврат каретки". Принтеры классифицируются по качеству печати. Матричный принтер формирует символы в виде матрицы точек и обеспечи вает нормальный, узкий и широкий форматы символов. Более совершенные матричные принтеры обеспечивают точечную графи ку, наклонный шрифт, жирную печать и двойную плотность, а также могут печатать, например, символы игральных карт и другие алфавитно-цифровые символы. Высококачественные печа тающие устройства ограничены набором символов на сменной "ромашке" или барабане, но обеспечивают отличное качество печати и большое разнообразие принтеров. Многие высокока чественные принтеры обеспечивают печать 10,12 или 15 симво лов на дюйм, а также пропорциональное расположение пробелов, подчеркивание, теневую и полужирную печать. Лазерные принте ры обладают преимуществами как для матричной графики, так и для качественной печати текстов. Другая классификация печатающих устройств связана с интер фейсами. Компьютеры IBM PC имеют параллельный интерфейс, позволяющий передавать одновременно восемь битов из процес сора на принтер. Кроме того, существует последовательный интерфейс, который выполняет побитовую передачу данных. Многие принтеры имеют буфер памяти, объемом в несколько тысяч байтов. Принтеры также могут принимать биты контроля на четность (нечетность). Принтеры должны "понимать" специ альные сигналы из процессора, например, для прогона листа, перевода строки или горизонтальной табуляции. В свою очередь, процессор должен "понимать" сигналы от принтера, указывающие на конец бумаги или состояние "занято". К сожалению многие типы принтеров по разному реагируют на сигналы процессора и одной из наиболее сложных проблем для программистов - обеспечить соответствие собственных программ имеющимся печатающим устройством. СИМВОЛЫ УПРАВЛЕНИЯ ПЕЧАТЬЮ ------------------------------------------------------------ Стандартными символами управления печатью являются сле дующие: Десятичн. Шест. Назначение Ассемблер для IBM PC. Глава 19 2 08 08 Возврат на шаг 09 09 Горизонтальная табуляция 10 0A Перевод строки 11 0B Вертикальная табуляция 12 0C Прогон страницы 13 0D Возврат каретки Горизонтальная табуляция. Горизонтальная табуляция (шест. 09) возможна только на принтерах, имеющих соответствующее обеспечение, иначе символы табуляции игнорируются. В последнем случае можно имитировать табуляцию выводом соответствующего числа пробелов. Перевод строки. Символ перевода строки (шест.OA) исполь зуется для прогона листа на один интервал. Соответственно для печати через два интервала используется два символа перевода строки. Прогон страницы. Установка бумаги после включения принте ра определяет начальную позицию печати страницы. Длина страницы по умолчанию составляет 11 дюймов. Ни процессор, ни принтер автоматически не определяют конец страницы. Если ваша программа продолжает печатать после конца страницы, то произойдет переход через межстраничную перфорацию на на чало следующей страницы. Для управления страницами необходи мо подсчитывать число напечатанных строк и при достижении максимального значения (например, 55 строк) выдать код прого на страницы (шест.OC) и, затем, сбросить счетчик строк в 0 или 1. В конце печати необходимо выдать символ "перевода строки" или "прогона страницы" для вывода на печать данные последней строки, находящиеся в буфере печатающего устройства. Использование последнего символа "прогон страницы" позволяет установить напечатанный последний лист в положение для отрыва. ФУНКЦИИ ПЕЧАТИ В РАСШИРЕННОЙ ВЕРСИИ DOS ------------------------------------------------------------ В операционной системе DOS 2.0 имеются файловые указатели, которые были показаны в главах по управлению экраном дисплея и дисковой печати. Для вывода на печатающее устройство используется функция DOS шест.40 и стандартный файловый номер 04. Следующий пример демонстрирует печать 25 символов из области HEADG: HEADG DB 'Industrial Bicycle Mfrs', 0DH, 0AH ... MOV AH,40H ; Запрос печати MOV BX,04 ; Файловый номер принтера MOV CX,25 ; 25 символов LEA DX,HEADG ; Область вывода INT 21H ; Вызов DOS Ассемблер для IBM PC. Глава 19 3 В случае ошибки операция устанавливает флаг CF и возвраща ет код ошибки в регистре AX. ПРОГРАММА: ПОСТРАНИЧНАЯ ПЕЧАТЬ С ЗАГОЛОВКАМИ ------------------------------------------------------------ Программа, приведенная на рис.19.1, аналогична программе на рис.9.1, за исключением того, что после ввода имен с клавиатуры выводит их не на экран, а на печатающее устрой ство. Каждая напечатанная страница содержит заголовок и через двойной интервал список введенных имен в следующем виде: List of Employee Names Page 01 Clancy Alderson Ianet Brown David Christie ... Программа подсчитывает число напечатанных строк и при дос тижении конца страницы выполняет прогон до начала следующей страницы. В программе имеются процедуры: D10INPT Выдает на экран запрос и затем вводит имя с кла виатуры. E10PRNT Выводит имя на печатающее устройство (длина име ни берется из вводного списка параметров); в конце страницы вызывает процедуру M10PAGE. M10PAGE Выполняет прогон на новую страницу, печатает за головок, сбрасывает счетчик строк и увели чивает счетчик страниц на единицу. P100UT Общая подпрограмма для непосредственного вывода на печатающее устройство. В начале выполнения необходимо напечатать заголовок, но не делать перед этим перевод страницы. Поэтому процедура M10PAGE обходит перевод страницы, если счетчик PAGECTR содержит 01 (начальное значение). Поле PAGECTR определено как PAGECTR DB '01' В начале выполнения необходимо напечатать заголовок, но не делать перед этим перевод страницы. Поэтому процедура M10PAGE обходит перевод страницы, если счетчик PAGECTR содержит 01 (начальное значение). Поле PAGECTR определено как PAGECTR DB '01' В результате будет сгенерировано число в ASCII коде - шест. 3031. Процедура M10PAGE увеличивает счетчик PAGECTR на 1 так, что значение становится последовательно 3032, 3033 и т.д. Эти значения корректны до 3039, далее следует 303A, что будет распечатано, как двоеточие (:). Поэтому, если в правом байте поля PAGECTR появляется шест.3A, то это значение Ассемблер для IBM PC. Глава 19 4 заменяется на шест.30, а к левому байту прибавляется единица. Таким образом шест.303A перекодируется в шест. 3130, т.е. в 10 в символьном представлении. ------------------------------------------------------------ ------------------------------------------------------------ Рис.19.1. Постраничная печать с заголовком. Проверка на конец страницы до (но не после) печати имени гарантирует, что на последней странице будет напечатано по крайней мере одно имя под заголовком. ПЕЧАТЬ ASCII-ФАЙЛОВ И ТАБУЛЯЦИЯ ------------------------------------------------------------ Табуляция, обеспечиваемая, например, видеоадаптерами, заключается в замене одного символа табуляции (код 09) несколькими пробелами при выводе так, чтобы следующая позиция была кратна 8. Таким образом, стандартные позиции табуляции являются 8, 16, 24 и т.д. Многие принтеры, однако, игнорируют символы табуляции. Поэтому, такая программа, как DOS PRINT, предназначенная для печати ASCII файлов (например ассемблерных исходных текстов) проверяет каждый символ, посылаемый на принтер. И, если обнаруживается символ табуляции, то программа выдает несколько пробелов до позиции кратной 8. Программа, приведенная на рис.19.2, выводит на экран запрос на ввод имени файла и, затем, печатает содержимое указанного файла. Эта программа в отличие от приведенной на рис.17.3 (вывод файлов на экран) осуществляет замену выводимых символов табуляции на соответствующее число пробелов. В результате символ табуляции в позициях от 0 до 7 приводит к переходу на позицию 8, от 8 до 15 - на 16 и т.д. Команды, реализующие данную логику, находятся в процедуре G10XFER после метки G60. Рассмотрим три примера обработки символа табуляции: Текущая позиция печати: 1 9 21 Двоичное значение: 00000001 00001001 00010101 Очистка трех правых битов: 00000000 00001000 00010000 Прибавление 8: 00001000 00010000 00011000 Новая позиция: 8 16 24 В программе организованы следующие процедуры: С10PRMP Запрашивает ввод имени файла. Нажатие только клавиши Return приводит к завершению работы программы. E10OPEN Открывает дисковый файл по указанному имени. G10XFER Контролирует конец сектора, конец файла, конец области вывода, символы "перевод строки" и табуля ции. Пересылает обычные символы в область вывода. Ассемблер для IBM PC. Глава 19 5 P10PRNT Распечатывает выводную строку и очищает область вывода. R10READ Считывает сектор из дискового файла. Коды "возврат каретки", "перевод строки" и "прогон страницы" действительны для любых принтеров. Можно модифици ровать программу для подсчета распечатываемых строк и выполнения прогона страницы (шест.OC) при достижении, например, строки 62. ------------------------------------------------------------ ------------------------------------------------------------ Рис.19.2. Печать ASCII файла. Некоторые пользователи предпочитают устанавливать символы "прогон страницы" в ASCII файлах с помощью текстового редактора в конкретных местах текста, например, в конце ассемблерных процедур. Кроме того, можно изменить программу для функции 05 базовой версии DOS. Эта функция выполняет вывод каждого символа непосредственно на принтер. Таким образом можно исключить определение и использование области вывода. ПЕЧАТЬ ПОД УПРАВЛЕНИЕМ БАЗОВОЙ DOS ------------------------------------------------------------ Для печати в базовой версии DOS необходимо установить в регистре AH код функции 05, а в регистр DL поместить распечатываемый символ и, затем, выполнить команду INT 21H следующим образом: MOV AH,05 ;Запрос функции печати MOV DL,char ;Распечатываемый символ INT 21H ;Вызов DOS С помощью этих команд можно передавать на принтер управляющие символы. Однако, печать, обычно, предполагает вывод полной или частичной строки текста и пошаговую обработку области данных, отформатированной по строкам. Ниже показазна программа печати полной строки. Сначала в регистр SI загружается начальный адрес области HEADG, а в регистр CX - длина этой области. Цикл, начинающийся по метке P20, выделяет очередной символ из области HEADG и посылает его на принтер. Так как первый символ области HEADG - "прогон страницы", а последние два - "перевод строки", то заголовок печатается в начале новой страницы и после него следует двойной интервал. HEADG DB 0CH,'Industrial Bicycle Mfrs',0DH,0AH,0AH LEA SI,HEADG ;Установка адреса и MOV CX,27 ; длины заголовка P20: MOV AH,05 ;Запрос функции печати Ассемблер для IBM PC. Глава 19 6 MOV DL,[SI] ;Символ из заголовка INT 21H ;Вызов DOS INC SI ;Следующий символ LOOP P20 Пока принтер не включен, DOS выдает сообщения "Out of pap er". После включения питания программа начинает работать нормально. Для прекращения печати можно нажать клавиши Ctrl/Break. СПЕЦИАЛЬНЫЕ КОМАНДЫ ПРИНТЕРА ------------------------------------------------------------ Выше уже был показан ряд команд, которые являются основными для большинства печатающих устройств. Кроме того существуют следующие команды: Десятичн. Шест. 15 0F Включить узкий формат 14 0E Включить широкий формат 18 12 Выключить узкий формат 20 14 Выключить широкий формат Есть команды, которые распознаются по предшествующему символу Esc (шест.IB). Некоторые из них в зависимости от печатающего устройства представлены ниже: 1B 30 Установить плотность 8 строк на дюйм 1B 32 Установить плотность 6 строк на дюйм 1B 45 Включить жирный формат 1B 46 Выключить жирный формат Коды команд можно посылать на принтер двумя разными способами: 1. Определить команды в области данных. Следующий пример устанавливает узкий формат, 8 строк на дюйм, затем печатает заголовок с завершающими командами "возврат каретки" и " перевод строки": HEADG DB 0FH, 1BH, 30H, 'Title...', 0DH, 0AH 2. Использовать команды с непосредственными данными: MOV AH,05 ;Запрос функции печати MOV DL,0FH ;Включить узкий формат INT 21H Все последующие символы будут печататься в узком формате до тех пор, пока программа не выдаст на принтер команду, выключающую этот формат. Ассемблер для IBM PC. Глава 19 7 Приведенные команды не обязательно работают на принтерах любых моделей. Для проверки возможных команд управления следует ознакомиться с руководством конкретного печатающего устройства. ПЕЧАТЬ С ПОМОЩЬЮ BIOS INT 17H ------------------------------------------------------------ Прерывание BIOS INT 17H обеспечивает три различные операции, специфицированные содержимым регистра AH: AH=0: Данная операция выполняет печать одного символа на три принтера по номерам 0,1 и 2 (стандартное значение - 0). MOV AH,00 ;Запрос функции печати MOV AL,char ;Символ, выводимый на печать MOV DX,00 ;Выбор принтера Э 0 INT 17H ;Вызов BIOS Если операция не может распечатать символ, то в регистре AH устанавливается значение 01. AH=1: Инициализация порта печатающего устройства: MOV AH,01 ;Запрос на инициализацию порта MOV DX,00 ;Выбор порта Э 0 INT 17H ;Вызов BIOS Данная операция посылает на принтер символ "прогон страницы", поэтому ее можно использовать для установки положения "верх страницы". Большинство принтеров выполняют данную установку автоматически при включении. AH=2: Чтение состояние порта принтера: MOV AH,02 ;Функция чтения состояния порта MOV DX,00 ;Выбор порта Э 0 INT 17H ;Вызов BIOS TEST AH,00101001B; Принтер готов? JNZ errormsg ;Нет - выдать сообщение об ошибке Назначение функций AH=1 и AH=2 состоит в определении состояния принтера. В результате выполнения этих функций биты регистра AH могут устанавливаться в 1: Бит Причина 7 Не занято 6 Подтверждение от принтера 5 Конец бумаги 4 Выбран 3 Ошибка ввода/вывода 0 Таймаут Ассемблер для IBM PC. Глава 19 8 Если прринтер включен, то операция возвращает шест.90 или двоичное 10010000 - принтер "не занят" и "выбран" - это нормальное состояние готовности. В случае неготовности принтера устанавливаются бит 5 (конец бумаги или бит 3 (ошибка вывода). Если принтер выключен, то операция возвращает шест.B0 или двоичное 10110000, указывая на "конец бумаги". Выполняя программу при выключенном принтере, BIOS не выдает сообщение автоматически, поэтому предполагается, что программа должна сама проверить и отреагировать на состояние принтера. Если программа не делает этого, то единственной индикацией будет мигающий курсор на экране дисплея. Если в этот момент включить принтер, то некоторые выходные данные могут быть потеряны. Следовательно, прежде чем использовать функции BIOS для печати, следует проверить состояние порта принтера и, если будет обнаружена ошибка, то выдать соответствующее сообщение. (Функции DOS выполняют эту проверку автоматически, хотя их сообщение "Out of paper" относится к различным состояниям). После включения принтера, вывод сообщений об ошибке прекращается и принтер начинает нормально работать без потери данных. В процессе работы принтер может выйти за страницу или быть нечаянно выключен. Поэтому в программах печати следует предусмотреть проверку состояния принтера перед каждой попыткой печати. ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ ------------------------------------------------------------ ъ Прежде чем выводить данные на печатающее устройство, включите принтер и вставьте в него бумагу. ъ Для завершении печати используйте символы "перевод строки" и "прогон страницы" для очистки буфера принтера. ъ Функции DOS для печати предусматривают вывод сообщений при возникновении ошибки принтера. Функции BIOS возвращают только код состояния. При использовании BIOS INT 17H проверяйте состояние принтера перед печатью. ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ ------------------------------------------------------------ 19.1. Напишите программу в расширенной версии DOS для а) прогона страницы; б) печати вашего имени; в) перевода строки и печати вашего адреса; г) перевода строки и печати названия вашего города/штата (республики); д) прогона страницы. 19.2. Переделайте программу из предыдущего вопроса для базовой версии DOS. Ассемблер для IBM PC. Глава 19 9 19.3. Закодируйте строку, в которой имеется следующая информация: возврат каретки, прогон страницы, включе ние узких букв, заголовок (любое имя) и выключение узких букв. 19.4. Измените программу из вопроса 19.1 для использования BIOS INT 17H. Обеспечьте проверку состояния принтера. 19.5. Измените программу из вопроса 19.1 так, чтобы пункты б), в), г) выполнялись по 5 раз. 19.6. Измените программу на рис.19.1 для выполнения в базовой версии DOS. 19.7. Измените программу на рис.19.2 так, чтобы распечатывае мые строки также выводились на экран. Ассемблер для IBM PC. Глава 20 18 ГЛАВА 20. Макросредства ------------------------------------------------------------ Макросредства Цель: Объяснить определение и использование ассемблерных макрокоманд. ВВЕДЕНИЕ ------------------------------------------------------------ Для каждой закодированной команды ассемблер генерирует одну команду на машинном языке. Но для каждого закодированного оператора компиляторного языка Pascal или C генерируется один или более (чаще много) команд машинного языка. В этом отношении можно считать, что компиляторный язык состоит из макро операторов. Ассемблер MASM также имеет макросредства, но макросы здесь определяются программистом. Для этого задается имя макроса, директива MACRO, различные ассемблерные команды, которые должен генерировать данный макрос и для завершения макропредел