Intdos, intdosx системный вызов функции dos

Содержание

Вывод на экран средствами DOS

DOS предоставляет следующие возможности вывода текстовой информации на экран:

-обращение к экрану как к файлу, с помощью прерывания DOS Int 21h с

-использование группы функций DOS из диапазона l. Ch (прерывание Int

21h) , реализующих посимвольный вывод, а также вывод строк.

Вывод на экран средствами файловой системы (Int 21h, функция 40h) осуществляется точно так же, как и запись в файл. Используются предопределенные дескрипторы 1 или 2, закрепленные за стандартными устройствами вывода и ошибки, соответственно (по умолчанию — экраном). Число выводимых символов указывается в регистре СХ, а адрес выводимой строки — в регистре DX. Коды 08h (забой), 0Ah (перевод строки), 0Dh (возврат каретки) и некоторые другие рассматриваются, как управляющие и приводят к выполнению соответствующих им действий. Число выводимых символов передается через регистр СХ, однако, если в строке встречается /Z (код 26), вывод прекращается. Дескриптор 1, закрепленный за стандартным устройством вывода, обеспечивает перенаправление вывода. Пусть, например, программа FILTXT содержит строки вывода через дескриптор 1. При запуске программы командой

ее вывод появится на экране, однако команда

приведет к автоматическому образованию файла MYFILE.DOC и записи в него всего вывода программы (на экран ничего не поступит); команда

направит вывод программы FILTXT в тот же файл MYFILE.DOC, при этом новая запись добавится к уже сущест­вующим, увеличив тем самым длину файла MYFILE.TXT.

Предопределенный дескриптор 2 (стандартная ошибка) всегда связан с экраном и не может быть перенаправлен.

Если требуется исключить для каких-то операторов вывода или для всей программы в целом возможность перенаправле­ния, то, помимо использования дескриптора стандартной ошиб­ки, можно открыть экран, как файл (с именем CON) функци­ей 3Dh, получить выделенный системой дескриптор, а затем использовать его в операциях вывода 40h:

screen db ‘CON’,0 ;Имя устройства

handlscr dw 0 ;Новый дескриптор

;Откроем новый дескриптор

mov АН,3Dh ;Функция открытия

mov AL.1 ;Доступ для записи

mov DX,off set screen ;Адрес имени устройства

mov handlscr,AX ;Получили дескриптор

Второй способ вывода на экран текстовой информации реализуется с помощью трех функций прерывания Int 21h:

02h — вывод символа;

06h — прямой ввод-вывод;

09h — вывод строки.

Функция 09h широко используется в системных программах (например, в драйверах) для вывода на экран информационных и диагностических сообщений. Перед вызовом прерывания адрес сообщения засылается в регистр DX; заканчивается сообщение символом «$». В сообщение могут быть включены управляющие коды (возврата каретки, перевода строки, забоя и др.), а также Esc-последовательности. Так же, как и при выводе через дескриптор 1 (функция 40h), вывод функцией 09h поступает на стандартное устройство вывода и при запуске программы может быть перенаправлен на другие внешние устройства с помощью операторов перенаправления.

Если в процессе вывода сообщения на экран с клавиатуры поступает код /C, срабатывает стандартная процедура обработки этого прерывания и вывод завершается (как и вся программа в целом). Для надежной обработки прерывания по /C следует включать режим BREAK (командой DOS BREAK ON).

Функция 02h вызывает передачу на экран (точнее — на стандартное устройство вывода) одного символа, помещаемого в регистр DL. Для вывода строки функцию следует использовать в цикле. В остальном она не отличается от функции 09h (перенаправление, обработка управляющих кодов, реакция на ввод с клавиатуры /C).

Функция 06h (прямой ввод-вывод через консоль) используется в тех случаях, когда надо исключить стандартную реакцию системы на ввод с клавиатуры /C. В остальном она действует так же, как функции 09h и 02h, однако обеспечивает не только вывод, но ввод. В случае вывода код ASCII передаваемого символа засылается в регистр DL; при вводе DL=FFh.

Средства DOS «в чистом виде» позволяют выводить на экран только черно-белый текст; возможности позиционирования текста на экране ограничиваются использованием символов возврата каретки (0Dh) и перевода строки (0Ah). Для вывода на экран средствами DOS цветных изображений следует использовать управляющие Esc-последовательности, реализуемые драйвером ANSI.SYS.

Дата добавления: 2015-07-13 ; Просмотров: 889 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

Функции DOS для ввода с клавиатуры

Функция 01h (т.е. прерывание 21h при значении AH=01h) вы­полняет ввод с клавиатуры одного символа. Если в момент вызова функции в буфере клавиатуры были символы (т.е. были нажатия клавиш до этого), то берется символ из буфера, в противном слу­чае система ждет, пока не будет нажата клавиша. Код введенного символа помещается в регистр AL. Введенный символ отобража­ется на экране (как говорят, выполняется эхо-отображение).

Например, пусть на клавиатуре была нажата клавиша «F». Тогда после вызова:

mov ah,01h
int 21h

в регистре AL будет содержаться число 46h, которое является кодом буквы F в коде ASCII.

Функция 01h проверяет также, не нажимал ли пользователь в ходе работы программы комбинацию клавиш Ctrl+C (или Ctrl+Break).

В этом случае управление передается на подпрограмму обра­ботки Ctrl+C, которая обычно прекращает выполнение программы пользователя.

Если на клавиатуре была нажата одна из клавиш, которым не соответствует никакой код ASCII (будем называть такие клавиши несимвольными; к ним относятся, например, Home, Ins, Page Up, F1, F10, стрелка) или комбинация из клавиши Alt, Ctrl, Shift с дру­гой клавишей, то функция 01h возвращает в регистре AL значение 0. В этих случаях следует еще раз вызвать ту же функцию, тогда будет выдан так называемый расширенный код данной клавиши или комбинации, согласно специальной таблице расширенных кодов.

Функция 08h работает аналогично 01h, за исключением того, что не выполняется эхо-отображение введенного символа.

Функция 07h работает аналогично 01h, за исключением того, что не выполняется эхо-отображение и не проверяется нажатие Ctrl+C.

Функция 06h может выполнять как ввод с клавиатуры, так и вывод на экран. Если в момент вызова регистр DL содержит зна­чение 0FFh, то данная функция выполняет ввод без ожидания. Это означает следующее. Если буфер клавиатуры содержит какие-либо символы (т.е. клавиши ранее нажимались), то флаг нуля ZF сбра­сывается в 0, а символ из буфера заносится в AL. Если же буфер пуст (нажатий не было), то устанавливается ZF=1, при этом значе­ние в AL не играет роли. Таким образом, эта функция не ждет, пока будет нажата клавиша, а сразу выдает какой-то результат.

Функция 06h не выполняет эхо-отображения и не проверяет нажатие Ctrl+C.

Функция 0Bh не выполняет ввод символа, а только проверяет, есть ли символы в буфере. Если есть, то устанавливается AL=0ffh, если нет, то – AL=00h. Выполняется также проверка на Ctrl+C.

Функция 0Ah выполняет буферизованный ввод строки с кла­виатуры. При этом символы вводятся один за другим, как при многократном применении функции 01h до тех пор, пока не будет введен код 0Dh (код клавиши Enter), завершающий строку. В ходе ввода строки пользователь может редактировать строку и, в част­ности, использовать забой. При вводе выполняется также про­верка на Ctrl+C.

При вызове функции 0Ah требуется, чтобы в регистре DX содер­жался адрес (в сегменте данных) области памяти (буфера), в кото­рую система поместит введенную строку. В первом байте этого буфера должна быть записана его длина, т.е. максимальное число символов (включая 0Dh), которое можно записать в буфер. Эта длина должна быть, по крайней мере, на 2 меньше, чем число зарезервированных байтов. После окончания ввода строки функ­ция помещает во второй байт буфера действительное число вве­денных символов (не считая 0Dh), а начиная с третьего байта буфера, раз­мещаются введенные символы. Последним всегда будет код 0Dh.

Например. Пусть требуется ввести строку длиной не более 10 символов. При этом в сегменте данных можно описать буфер, например таким образом:

BUFFER db 11 ;Первый байт буфера
ENTERED db (?) ;Число введенных символов
STRING db 11 dup (?) ;Введенные символы

Сам же ввод выполняется командами:

lea DX,BUFFER ;Адрес буфера — в DX
mov AH,0Ah ;Номер функции — в AH
int 21h ;Вызов функции

Пусть при этом пользователь набрал 6 символов: «Hallo!» и нажал клавишу Enter. После вызова функции в байте entered будет число 6, в первых 6 байтах массива STRING будут коды введенных символов, в седьмом байте – код 0Dh, а оставшиеся 4 байта будут иметь неопределенные значения.

Функция 0Ch вначале очищает буфер клавиатуры (т.е. «забывает» предыдущие нажатия клавиш), а потом выполняет любую из функций 01h, 06h, 07h, 08h или 0Ah. Номер этой функ­ции задается в регистре AL. Если задано иное число, то выполня­ется только очистка буфера. Кроме того, всегда выполняется проверка на Ctrl+C.

Не нашли то, что искали? Воспользуйтесь поиском:

Лучшие изречения: Как то на паре, один преподаватель сказал, когда лекция заканчивалась — это был конец пары: «Что-то тут концом пахнет». 8378 — | 8008 — или читать все.

188.64.174.135 © studopedia.ru Не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования. Есть нарушение авторского права? Напишите нам | Обратная связь.

Отключите adBlock!
и обновите страницу (F5)

очень нужно

Ассемблер

Прерывание 21h: общие функции DOS

Все функции DOS вызываются с помощью прерывания 21h (в десятичной нотации 33). Первая версия DOS содержала 42 функции. Во второй к ним добавлено еще 33 функции, которые сохраняются во всех последующих версиях. Выбор конкретной функции осуществляется путем записи соответствующего номера в регистр AH.

Функция 02: вывод одного символа на экран

Для вывода одного символа на экран ПК используется

функция 02 прерывания 21h:

Выводимый символ высвечивается в позиции курсора (что бы там ни было записано), после чего курсор сдвигается на одну позицию вправо. Если курсор находился в конце строки экрана, то он перемещается на начало следующей строки, а если курсор был в конце последней строки экрана, то содержимое экрана сдвигается на одну строку вверх, а внизу появляется пустая строка, в начало которой и устанавливается курсор.

Особым образом осуществляется вывод символов с кодами 7, 8, 9, 10 (0Ah) и 13 (0Dh). Символ с кодом 7 (bell, звонок) на экране не высвечивается (и курсор не сдвигается), а вызывает звуковой сигнал. Символ с кодом 8 (backspase, шаг назад) возвращает курсор на одну позицию влево, если только он не был в самой левой позиции строки. Символ с кодом 9 (tab, табуляция) смещает курсор вправо на ближайшую позицию, кратную 8. Символ с кодом 10 (line feed, перевод строки) перемещает курсор в следующую строку экрана, оставляя его в той же колонке. Символ с кодом 13 (carrige returne, возврат каретки) устанавливает курсор на начало текущей строки; вывод подряд символов с кодами 13 и 10 означает перевод курсора на начало следующей строки.

Функция 9: вывести строку на экран дисплея

Для вывода на экран строки (последовательности символов) можно, конечно, использовать функцию 02, однако сделать это можно и за один прием с помощью функции 09 прерывания 21h:

DS:DX := начальный адрес строки

Перед обращением к этой функции в регистр DS должен быть помещен номер того сегмента памяти, в котором находится выводимая строка, а в регистр DX — смещение строки внутри этого сегмента. При этом в конце строки должен находиться символ $ (код 24h), который служит признаком конца строки и сам не выводится.

Хотя эта функция может оказаться намного удобнее функций побайтового вывода на экран (функция 2 и 6), она имеет тот недостаток, что вполне обычный символ $ используется как ограничитель строки. Это еще один побочный продукт совместимости с CP/M.

Расширенные функции операционной системы DOS в качестве ограничителя строки используют CHR$(0). Это соответствует соглашениям, принятым в операционной системе UNIX и языке программирования Си.

Среди функций DOS нет такой, которая выводит числа. Такую операцию, если надо, приходится реализовывать на основе рассмотренных функций.

Функция 4Ch: завершение программы

Завершив все свои действия, программа обязана вернуть управление операционной системе, чтобы пользователь мог продолжить работу на ПК. Такой возврат реализуется функцией 4Ch прерывания 21h, которую помещают в конце программы:

Каждая программа, вообще говоря, обязана сообщить, успешно или нет она завершила свою работу. Дело в том, что любая программа вызывается из какой-то другой программы (например, из операционной системы), и иногда вызвавшей программе, чтобы правильно продолжить работу, надо знать, выполнила ли вызванная программа все, что надо, или она проработала с ошибкой. Такая информация передается в виде кода завершения программы (некоторого целого числа), который должен быть нулевым, если программа проработала правильно, и ненулевым (каким именно — оговаривается в каждом случае особо) в противном случае. (Узнать код завершения вызванной программы можно с помощью функции 4Dh прерывания 21h.) Потребуется этот код или нет, программа все равно должна выдать его.

Intdos, intdosx системный вызов функции dos

Дистрибутив операционной системы MS-DOS состоит, в зависимости от версии, из одной или нескольких дискет. На них расположены файлы собственно операционной системы IO.SYS, MSDOS.SYS, командный процессор COMMAND.COM, файлы внешних команд операционной системы (FORMAT, FDISK и т.п.), драйверы и другие файлы.

Файл IO.SYS содержит расширение базовой системы ввода/вывода и является интерфейсом между операционной системой и BIOS. Расширение используется операционной системой для взаимодействия с аппаратурой компьютера и BIOS.

Файл MSDOS.SYS является в некотором смысле набором программ обработки прерываний, в частности прерывания INT 21H. Это тело операционной системы.

Командный процессор COMMAND.COM предназначен для организации диалога с оператором. Он анализирует вводимые оператором команды и организует их выполнение. Так называемые внутренние команды (DIR, COPY и т.д.) обрабатываются именно командным процессором. Программист имеет возможность написать свой собственный командный процессор и подключить его вместо стандартного. Новый командный процессор должен выполнять все функции, которые раньше выполнял стандартный COMMAND.COM.

Драйверы (обычно это файлы, имеющие расширение имени .SYS) представляют собой программы, обслуживающие различную аппаратуру. Эти программы имеют специальный формат и будут подробно описаны в книге. Применение драйверов легко решает проблемы использования новой аппаратуры — достаточно написать для нового устройства драйвер и подключить его к операционной системе. Прикладные программы взаимодействуют с устройствами через драйвер, поэтому они не будут меняться при изменениях в аппаратуре. Например, новое дисковое устройство может иметь другое количество дорожек и секторов, другие управляющие команды. Все это учитывается драйвером, а прикладная программа будет работать с новым диском как и раньше, используя прерывания MS-DOS.

Файлы внешних команд операционной системы содержат программы-утилиты для выполнения разнообразных операций, таких как форматирование дисков, сортировка файлов, печати текстов и других.

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

Файлы операционной системы выделяются своим особым расположением на диске (кроме COMMAND.COM) — эти файлы должны находиться в специально отведенном для них месте. Если вам нужно подготовить дискету как системную (т.е. такую, с которой можно загружать операционную систему), для переноса файлов операционной системы следует использовать специальные утилиты.

Самый простой способ подготовки системной дискеты — использовать команду FORMAT с опцией /S, например:

В этом случае после форматирования на дискету будут перенесены файлы операционной системы. При использовании команды текущим должен быть корневой каталог системного диска, например, диска С:.

Если вы собираетесь обновить версию операционной системы (например, вместо MS-DOS 3.30 установить MS-DOS 4.01), не обязательно заново переформатировать весь диск. Загрузив новую версию с дискеты, для переноса новых системных файлов используйте команду SYS:

Файл COMMAND.COM скопируйте обычным способом.

Если вам надо сделать дискету системной, а ее форматирование нежелательно (дискета содержит важную информацию), воспользуйтесь программой Norton Disk Doctor или аналогичной. Программа освободит место в начале диска для операционной системы, переписав располагавшиеся там данные на свободное место в конце дискеты, затем запишет системные файлы и даже скопирует файл COMMAND.COM.

Утилита FDISK предназначена для подготовки к работе жесткого диска. Она разбивает диск на участки, называемые разделами.

На одном физическом диске могут быть разделы, принадлежащие разным операционным системам. Один из разделов — активный, операционная система загружается из активного раздела.

Для MS-DOS утилита FDISK позволяет создать первичный и вторичный разделы. В первичном разделе располагается системный диск C:, с которого выполняется загрузка операционной системы, вторичный раздел может быть разделен на логические диски (D:, E:, F: и т.д.). Диски, располагающиеся во вторичном разделе, не могут быть системными.

Заметим, что только MS-DOS версии 4.01, 5.0 и Compaq DOS 3.31 позволяют создавать логические диски размером более 32 мегабайт. Это связано с тем, что другие версии DOS используют 16-разрядную адресацию секторов диска, что недостаточно для дисков больших размеров.

Очень часто вместо утилиты FDISK для подготовки жесткого диска используются диск-менеджеры. Это такие программы, как Advanced Disk Manager, Speed Stor и т.д. Используя свои собственные форматы разделов и таблиц разделов (и свои драйверы дисковых устройств), диск-менеджеры предоставляют такие дополнительные возможности, как защита логического диска от записи или организация парольной защиты данных на диске, создание логических дисков размером более 32 мегабайт.

Однако не всегда применение диск-менеджеров может привести к желаемому результату. Защита от несанкционированного доступа часто легко преодолевается, мощные ситемы защиты сильно привязаны к конкретной версии операционной системы (например, WatchDog, очень мощная система защиты, требует только DOS версии 3.20).

Кроме того, драйверы, используемые диск-менеджерами могут замедлить работу дисковой подсистемы компьютера.

Некоторые программы, особенно защищенные от копирования, отказываются работать на диске, подготовленном не утилитой FDISK. Причины этого мы увидим, когда будем обсуждать проблемы защиты программ от несанкционированного копирования.

Перейдем к процедуре начальной загрузки операционной системы.

При включении питания компьютера управление передается базовой системе ввода/вывода, BIOS.Она выполняет проверку аппаратных узлов компьютера, формирует начальную часть таблицы векторов прерываний, инициализирует устройства и начинает процесс загрузки операционной системы.

Загрузка начинается с того, что BIOS делает попытку прочитать самый первый сектор дискеты, вставленной в дисковод А: (на загрузочной дискете этот сектор содержит загрузчик операционной системы). Если в дисковод вставлена системная дискета, с нее считывается загрузчик и ему передается управление.

Если дискета не системная, т.е. не содержит загрузочной записи, на экран выдается сообщение с просьбой заменить дискету.

Если же дискеты в дисководе А: вообще нет, то BIOS читает основную загрузочную запись диска С: (Master Boot Record). Обычно это самый первый сектор на диске. Управление передается загрузчику, который находится в этом секторе. Загрузчик анализирует содержимое таблицы разделов (она также находится в этом секторе), выбирает активный раздел и читает загрузочную запись этого раздела. Загрузочная запись активного раздела (Boot Record) аналогична загрузочной записи, находящейся в первом секторе системной дискеты.

Загрузочная запись активного раздела считывает с диска файлы IO.SYS и MSDOS.SYS (именно в этом порядке). Затем считываются и загружаются резидентные драйверы. Начинается формирование связанного списка драйверов устройств. Анализируется содержимое файла CONFIG.SYS, загружаются описанные в этом файле драйверы. Сначала загружаются драйверы, описанные параметром DEVICE, затем (только в MS-DOS версии 4.х и 5.0) резидентные программы, указанные операторами INSTALL. После этого считывается командный процессор и ему передается управление.

Командный процессор состоит из трех частей — резидентной, инициализирующей и транзитной. Первой загружается резидентная часть. Она обрабатывает прерывания INT 22H, INT 23H, INT 24H, управляет загрузкой транзитной части. Эта часть командного процессора обрабатывает ошибки MS-DOS и выдает запрос пользователю о действиях при обнаружении ошибок.

Инициализирующая часть используется только в процессе загрузки операционной системы. Она определяет начальный адрес, по которому будет загружаться пользовательская программа и инициализирует выполнение файла AUTOEXEC.BAT.

Транзитная часть командного процессора располагается в старших адресах памяти. В этой части находятся обработчики внутренних команд MS-DOS и интерпретатор командных файлов с расширением имени .BAT. Транзитная часть выдает системное приглашение (например, А:\> ), ожидает ввода команды оператора с клавиатуры или из пакетного файла и организует их выполнение.

После загрузки командного процессора и выполнения начальных процедур, перечисленных в файле AUTOEXEC.BAT, подготовка системы к работе завершается.

Для того чтобы правильно работать с системным программным и аппаратным обеспечением, нужно четко представлять себе механизм взаимодействия прикладной программы с компьютером. На рис. 1.1 показаны функциональные связи программы с программно-аппаратным обеспечением IBM PC.

Как правило, ядро DOS разделяют на несколько подсистем, каждая из которых отвечает за выполнение той или иной задачи. Как показано на рисунке, обычно выделяются следующие подсистемы:

  • файловая система;
  • система управления памятью;
  • система управления программами;
  • система связи с драйверами устройств;
  • система обработки ошибок;
  • службу времени;
  • систему ввода/вывода консоли оператора.

Эти подсистемы общаются с аппаратурой через BIOS, драйверы или напрямую. Прикладное программное обеспечение может вызывать подсистемы DOS, работать с BIOS или непосредственно с аппаратурой. Обратите, однако, внимание на то, что прикладные программы могут обращаться к драйверам только через соответствующую подсистему DOS.

Очевидно также, что чем выше уровень интерфейса прикладной программы и аппаратуры, тем меньше программа будет зависеть от особенностей аппаратуры.

Рассмотрим подсистемы DOS отдельно.

Файловая система.

Файловая система является одной из важнейших подсистем DOS. Она используется как в процессе загрузки операционной системы, так и в процессе ее работы. Сама операционная система записана на системном диске в виде файлов (IO.SYS, MSDOS.SYS, COMMAND.COM, драйверы, внешние команды и т.д.). Все прикладные программы и вообще все программы и данные для них хранятся на дисках в виде файлов, поэтому можно сказать, что файловая система — ключевая подсистема DOS.

Для обращения к файловой системе прикладная программа должна использовать специально предназначенные для этого функции прерывания DOS. Эти функции выполняют все файловые операции — создание, удаление файлов и каталогов, буферизованная и не буферизованная запись или чтение, получение справочной информации о состоянии файловой системы и другие. Файловые операции будут кратко описаны в обзоре прерываний DOS, кроме того, файловой системе полностью посвящена третья книга первого тома.

Файловая система работает с дисками через драйверы. Драйверы, в свою очередь, пользуются сервисом BIOS.

На уровне BIOS выполняются элементарные операции с диском, такие как чтение/запись секторов, форматирование и т.п. Этот низкий уровень доступен и прикладной программе, но обычно она пользуется функциями прерывания DOS, выполняющими все необходимые действия по обслуживанию каталогов и таблицы размещения файлов (File Allocation Table — FAT). Программы защиты от несанкционированного доступа или копирования вынуждены обращаться к средствам более низкого уровня, вызывая прерывания BIOS, или даже работать с контроллером дисковода через порты ввода/вывода.

Используя подсистему DOS, отвечающую за связь с драйверами, прикладные программы могут также выполнять элементарные операции с диском, такие как форматирование.

Система управления памятью.

Эта подсистема DOS используется для распределения памяти запускаемым программам.

DOS управляет памятью с помощью блоков MCB (Memory Control Block). Память разбивается на блоки; каждому блоку предшествует MCB, в котором записаны характеристики блока памяти. Для каждой вновь запускаемой программы DOS создает определенное количество блоков MCB. При освобождении памяти или при выполнении запросов на получение дополнительной памяти DOS также использует блоки MCB, проверяя при этом правильность их содержимого.

Все блоки MCB располагаются друг за другом. Адрес первого блока хранится в векторной таблице связи, CVT, о которой мы будем говорить в главе 2. Там же будет описан формат блока управления памятью.

Прикладная программа может заказать для себя дополнительные блоки памяти. Для этого она обращается к системе управления памятью, используя функции прерывания 21h DOS.

Система управления программами.

При запуске программы DOS выполняет несколько операций. Сначала она обращается к системе управления памятью, чтобы подготовить блоки памяти для запускаемой программы. С помощью файловой системы файл, содержащий программу, загружается в память, после чего программа (это относится только к файлам типа .exe) настраивается на конкретный физический адрес. Только после этого программе передается управление.

Как известно, в MS-DOS существуют два формата выполняемых программ — .com и .exe. Способы запуска этих программ сильно различаются. Система управления программами автоматически распознает их и загружает в память по-разному. Мы еще вернемся к описанию различий между этими типами программ.

Другая задача, решаемая ситемой управления программами — запуск программ из программ и загрузка «программных перекрытий» — оверлеев. Если не все модули большого программного комплекса нужны одновременно, вы можете разбить комплекс на несколько частей. Это могут быть либо несколько отдельных программ, либо несколько оверлейных модулей. Каждый из этих способов имеет свои преимущества и недостатки; оба они пригодны для экономии памяти.

И наконец, последняя функция системы управления программами — работа с резидентными программами. Если вам надо, чтобы после завершения своей работы программа осталась резидентной в памяти, вы, как и в случае завершения обычной программы, обращаетесь к системе управления программами через соответствующую функцию прерывания DOS 21h.

Система связи с драйверами устройств.

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

Возможно, что запрет на непосредственный вызов драйверов введен для обеспечения совместимости с будущими версиями операционной системы, в которых механизм вызова драйверов может измениться. Однако, используя сведения, приведенные в этой книге, вы сможете обойти этот запрет и обратиться непосредственно к драйверу. При этом вам придется использовать некоторые недокументированные прерывания DOS, что само по себе нежелательно из-за возможной потери совместимости с другими версиями операционной системы.

Для управления состоянием устройства ввода/вывода или состоянием драйвера используется специальная функция 44h прерывания DOS 21h. Эта функция предназначена для обмена управляющей информацией между прикладной программой и драйвером.

Система обработки ошибок.

Система обработки ошибок DOS проста и удобна. Для кодирования ошибок как правило используется флаг переноса (CARRY, CF). Если после обращения к прерыванию DOS флаг переноса установлен в 1, произошла ошибка. Для того чтобы проанализировать ошибку и предпринять какие-то действия, можно вызвать соответствующую функцию DOS, которая вернет уточняющую информацию об ошибке и предоставит соответствующие рекомендации (разумеется, лишь в виде кодов, находящихся в регистрах процессора).

Если произошла критическая ошибка ввода/вывода (например, прочитать дискету невозможно), вызывается стандартная процедура DOS, выводящая на экран запрос о дальнейших действиях. Пользовательская программа может подключить вместо системной свою программу обработки критических ошибок. Подробнее об обработке ошибок будет сказано в разделе 1.6.

Служба времени.

Компьютер обычно оборудуется системными часами. Это могут быть КМОП-часы с питанием от аккумулятора, содержимое которых не сбрасывается при выключении питания компьютера, или таймер, регулярно вырабатывающий прерывания. В любом случае операционная система ведет подсчет времени и хранит текущие показания часов и дату.

Программа может опросить часы, обратившись к DOS с запросом через одну из функций прерывания 21h, или установить новое состояние часов.

Операционная система содержит драйвер устройства CLOCK$. Прикладная программа может обратиться к этому устройству для чтения показания часов или для установки часов. В книге 2 первого тома приведен пример программы для работы с устройством CLOCK$.

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

Ввод/вывод на консоль оператора.

Консоль оператора состоит из двух устройств — клавиатуры и дисплея. Эти два устройства обслуживаются одним драйвером — драйвером консоли CON. Т.е. можно считать, что в компьютере имеется устройство — консоль — с именем CON.

Операционная система обслуживает консоль с помощью функций прерывания 21h, обеспечивающих ввод и вывод символов на устройство CON. Для работы с физической клавиатурой и дисплейным адаптером этот драйвер использует прерывания BIOS.

Другие подсистемы DOS.

DOS имеет набор драйверов для работы с печатающими устройствами и последовательными портами, которые обеспечивают прием/передачу символов и управление режимами работы устройств.

Кроме того, для печати текста в фоновом режиме в состав дистрибуции DOS входит программа PRINT.COM. Эта практически единственная «мультизадачная» утилита операционной системы является примером стандартной резидентной программы. Она позволяет выполнять параллельно с печатью текста другую работу (например, редактирование другого текста).

Специально следует отметить драйверы электронного диска и кэш-памяти. Драйвер электронного диска называется RAMDRIVE.SYS. Этот драйвер организует в расширенной или в дополнительной памяти компьютера быстрый псевдо-диск. Можно организовать электронный диск и в основной памяти, но основной памяти всегда мало!

Операционная система MS-DOS версий 4.01 и 5.0 имеет в своем составе систему управления дополнительной и расширенной памятью, которая реализуется драйвером HIMEM.SYS. Этот драйвер позволяет программам, составленным специальным образом, использовать расширенную или дополнительную память для хранения данных (но не для выполнения программ).

Если подключен драйвер HIMEM.SYS, то с помощью драйвера SMARTDRV.SYS можно создать кэш-память для жесткого диска. Особенно эффективно применение кэш-памяти для работы с базами данных, когда вам периодически требуется одна и та же информация. В следующий раз, когда информация потребуется, она будет доступна без обращения к диску.

Такое широко распространенное и ставшее стандартным для любого персонального компьютера устройство как мышь не поддерживается операционной системой. Для использования мыши следует подключить драйвер, который обычно поставляется вместе с этим устройством.

Другие устройства ввод/вывода (сканеры, плоттеры, стримеры и т.п.) также не поддерживаются DOS. Для этих устройств фирмы поставляют драйверы, которые надо подключить к операционной системе.

Как правило, любая программа работает с тем или иным устройством ввода/вывода. Программы для первых ЭВМ работали непосредственно с портами и регистрами этих устройств. Модули, выполняющие такие стандартные действия, как ввод данных с перфокарт или печать результатов вычислений, входили в состав пользовательских программ.

В начале своего развития микропроцессорные системы имели в своем составе программу, называемую «монитор». Эта программа обычно находилась в постоянном запоминающем устройстве и обслуживала устройства ввода/вывода: клавиатуру, дисплей, кассетный накопитель на магнитной ленте и др. Диалоговая часть монитора позволяла выполнять некоторые операторские функции: загрузку и запуск программы, отладку программы в пошаговом режиме, печать текстов, просмотр и редактирование содержимого памяти и т.п. Но самое главное — прикладные программы, составленные для этих систем, могли пользоваться модулями монитора для работы с периферийной аппаратурой и для выполнения других функций.

Программа уже не содержала все необходимые для ее работы модули, а пользовалась «стандартными» услугами программы-монитора. Такая организация программы не только уменьшила размер ее загрузочного модуля, но и позволила программистам сосредоточить свои усилия на решении основной задачи.

Как программа пользовалась услугами монитора? Механизм взаимодействия программы пользователя и монитора был реализован по-разному в разных системах. В худшем случае прикладная программа пользовалась известными абсолютными адресами модулей монитора, в лучшем — использовала специальные таблицы адресов программных модулей.

К сожалению, разные системы были несовместимы по составу модулей монитора и механизму их вызова, что сильно затрудняло, если не совершенно исключало их программную совместимость.

В первом массовом персональном компьютере IBM PC модули обслуживания стандартной периферии были записаны в постоянном запоминающем устройстве. Совокупность этих модулей (плюс программа начальной инициализации и тестирования) называется базовой системой ввода/вывода — Basic Input/Output System. Общепринятое сокращение — BIOS.

Выпускаемые различными фирмами компьютеры, совместимые с IBM PC, могут немного отличаться по типу периферийного оборудования, но для достижения совместимости с IBM PC модули BIOS нивелируют эти различия, предоставляя в распоряжение программы пользователя стандартный набор модулей для работы с устройствами ввода/вывода.

Не будет преувеличением сказать, что одна из причин такого невиданного успеха компьютера IBM PC на рынке персональных компьютеров — наличие хорошо продуманного стандартного интерфейса модулей BIOS и прикладных программ. Именно благодаря этому интерфейсу достигается почти стопроцентная совместимость по программному обеспечению компьютеров этого типа, выпускаемых разными фирмами.

В этом разделе книги мы расскажем о том, как прикладные программы, составленные для компьютера, совместимого с IBM PC, могут пользоваться модулями BIOS для работы со стандартной периферией, затем приведем краткий обзор основных модулей BIOS.

Напомним вам, что такое программные прерывания, так как именно они используются для вызова модулей BIOS.

В начале оперативной памяти персонального компьютера (в пределах первого килобайта) находится так называемая векторная таблица прерываний. Она состоит из 256 ячеек, хранящих адреса программ-обработчиков прерывания. Мы будем подробно изучать эту таблицу в главе 4, а сейчас вспомним машинную команду INT .

По этой команде содержимое ячейки векторной таблицы прерываний с номером n помещается в адресные регистры процессора, причем в стеке запоминается текущее содержимое адресных регистров. Управление передается по адресу, записанному в ячейке таблицы. Программа-обработчик прерывания должна заканчиваться командой IRET, по которой из стека извлекается старое значение адресных регистров и управление передается обратно в программу, вызвавшую прерывание командой INT .

Вообще говоря, процедура вызова и обработки программного прерывания похожа на процедуру вызова подпрограммы. Отличие заключается в том, что вызывающая программа «не знает» абсолютного адреса модуля обработки прерывания в памяти. Поэтому работа программ не зависит от адресов расположения модулей обработчиков прерывания.

Для вызова модуля BIOS программа использует команду INT с соответствующим номером n. Программа передает параметры модулям BIOS через регистры процессора, результат работы модуля возвращается также в регистрах.

Не все номера прерываний n используются BIOS. Часть из них предназначена для аппаратных прерываний от устройств ввода/вывода, часть зарезервирована для DOS, часть — для программ пользователя.

Подробно прерывания BIOS будут изучаться во втором томе, так как описание этих прерываний трудно отделить от описания особенностей аппаратуры. Приводимый здесь обзор предназначен в основном для иллюстрации основных возможностей BIOS по обслуживанию периферии, поэтому в обзор вошли не все прерывания BIOS, а только самые важные. Остальные прерывания будут изучаться по мере необходимости при изложении соответствующего материала.

Получение информации об оборудовании


INT 11h — Получить список оборудования.

Прежде чем пытаться работать с каким-либо устройством ввода/вывода, следует убедиться в том, что оно есть в составе оборудования компьютера. В процессе инициализации тестовые модули, находящиеся в BIOS, динамически определяют состав аппаратного обеспечения машины и записывают конфигурацию системы в специально отведенную для этого ячейку памяти.

Программа, вызывая прерывание INT 11h, получает в регистре AX содержимое этой ячейки. Каждый бит в слове конфигурации отвечает за соответствующее устройство.

Анализируя слово конфигурации, программа может узнать, входят ли в состав оборудования компьютера дискеты и если входят, то сколько дисководов имеется в наличии, присутствует ли арифметический сопроцессор, какой начальный режим дисплейного адаптера используется, сколько в системе принтеров, адаптеров последовательного интерфейса RS232, подключен ли игровой адаптер (джойстик)?

Обычно прикладная программа не работает сама с аппаратурой, а пользуется услугами операционной системы. При обращении к стандартной аппаратуре через операционную систему программа пользователя получит признак ошибки, если запрашиваемое устройство отсутствует. Программы, составленные на языке программирования Си при использовании библиотеки эмуляции арифметического сопроцессора, сами определяют, имеется сопроцессор или нет, и не пытаются пользоваться отсутствующим устройством. Операции сопроцессора эмулируются центральным процессором и программа просто работает медленнее.

Но если программа обращается непосредственно к портам ввода/вывода отсутствующего устройства, это может привести в лучшем случае к зависанию системы.

INT 12h — Получить размер основной памяти.

Сказанное выше справедливо и по отношению к оперативной памяти. Для работы некоторых программ требуется достаточное количество памяти. Прерывание INT 12h возвращает в регистре AX количество имеющихся блоков памяти размером в один килобайт. Анализируя эту величину, программы могут при нехватке памяти либо вывести на экран соответствующее сообщение и отказаться от работы, либо изменить алгоритмы работы, организовав, например, «виртуальную» память на диске или просто записывая в файл промежуточные результаты.

Если Ваш компьютер оборудован расширенной памятью (адресное пространство этой памяти находится выше границы в 1 мегабайт), размер этой памяти в килобайтах можно узнать, вызвав прерывание INT 15h со значением регистра AX, равным 8800h.

Работа с дисплейным адаптером.

Прерывание INT 10h выполняет все многочисленные операции по обслуживанию дисплейного адаптера.

При вызове прерывания INT 10h, как и при вызове многих других прерываний, регистр AH содержит номер функции, которую требуется выполнить. Остальные регистры при вызове прерывания содержат операнды.

Программирование дисплейного адаптера — сложная задача. Функции, выполняемые прерыванием INT 10h обширны, полностью они будут описаны во втором томе книги. Приведем краткий обзор функций прерывания INT 10h.

00h — Задание видеорежима.

Эта функция обычно вызывается первой при начале работы с дисплейным адаптером или при необходимости изменить текущий режим адаптера. Что здесь имеется в виду?

Напомним, что дисплейный адаптер может работать либо в текстовом, либо в графическом режиме. На самом деле существует несколько текстовых и несколько графических режимов, различающихся количеством строк и столбцов, способом представления цвета и т.д.

В процессе инициализации BIOS задает начальный режим адаптера исходя из его типа. Если Вашей программе нужен другой режим, отличный от исходного, она должна использовать эту функцию. При этом необходимо учитывать, что дисплейные адаптеры могут поддерживать не все режимы.

01h — Установить характеристики курсора.

С помощью этой функции вы можете установить размер и форму курсора, сделать курсор мигающим или убрать его совсем.

02h — Установить положение курсора.

Эта функция позволяет управлять расположением курсора на экране, в частности, один из способов убрать курсор — расположить его за пределами экрана, например, на несуществующей 26 строке.

03h — Получить положение курсора.

Программа может узнать в любое время, где расположен курсор. Это может потребоваться ей, например, для того, чтобы переместить курсор в следующую позицию (вправо, вверх, вниз, на 10 символов левее текущего положения и т.д.).

04h — Получить положение светового пера.

Световое перо используется относительно редко, однако если оно есть, то функция 04h позволит вам работать с этим устройством.

05h — Выбрать активную страницу дисплейной памяти.

Компьютер хранит, как правило, не один отображаемый образ экрана, а несколько. Для этого видеопамять (память для хранения видеоизображения, находится на плате видеоконтроллера) разбивается на так называемые страницы. Отображается только активная страница видеопамяти.

Используя механизм страниц, программа может заранее подготовить изображение в неактивной странице, затем сделать подготовленную страницу активной. Изображение новой страницы мгновенно появится на экране.

Некоторые отладчики программ используют одну страницу видеопамяти для отлаживаемой программы, другую — для выдачи своих диагностических сообщений.

06h, 07h — Прокрутка (скроллинг) окна вверх/вниз.

С помощью этих функций вы сможете переместить выбранную область окна на заданное число строк вверх или вниз. Освободившееся место будет заполняться пустыми строками. Одно из применений этой функции — полная очистка экрана.

08h, 09h — Прочитать/записать символ и атрибут.

С помощью этих функций можно прочитать или записать символ и его атрибут. При записи символа можно задать число повторений. Функцию записи с повторением удобно использовать для заполнения области экрана каким-либо символом.

Запись/чтение символа начинается с текущего положения курсора.

0Ah — Записать символ.

Эта функция предназначена для записи символа в видеопамять без задания для него индивидуального значения атрибута. Используется текущий атрибут. Можно задавать кратность записи.

0Bh — Выбрать цветовую палитру.

Эта функция позволяет управлять цветом рамки вокруг изображения в текстовом режиме и цветом фона в графическом режиме (для адаптеров EGA, VGA).

0Ch, 0Dh — Записать/прочитать графическую точку.

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

0Eh — Запись символа на экран в стиле TTY.

После записи символа на экран курсор продвигается на следующую позицию, при этом обрабатываются такие управляющие символы, как BEL (подача звукового сигнала), возврат на одну позицию, перевод строки, возврат к началу строки.

0Fh — Прочитать текущий видеорежим.

Если Ваша программа изменяет видеорежим, она может сохранить старый видеорежим, получив его с помощью этой функции.

Кроме того, функция возвращает количество столбцов на экране и номер текущей активной дисплейной страницы.

10h, 11h, 12h — Обслуживание адаптера EGA.

Эти функции работают только при использовании дисплейных адаптеров EGA и VGA. Они позволяют устанавливать свою цветовую палитру, загружать знакогенератор (например, шрифтом для русских букв) и выполнять некоторые другие функции.

13h — Запись строки.

Для машин класса AT и выше при наличии дисплейных адаптеров EGA или VGA эта функция позволяет вывести на экран произвольную строку символов заданной длины, с заданным атрибутом и в заданном месте экрана. Можно также задать номер дисплейной страницы.

Если вы не можете использовать эту функцию (Ваш компьютер — XT или дисплейный адаптер — CGA), единственный способ вывести на экран строку символов с помощью прерывания INT 10h — вызывать в цикле функции 09h, 0Ah или 0Eh для вывода строки по одному символу.

Обслуживание клавиатуры.

Обработчик прерывания INT 16h выполняет несколько функций, связанных с обслуживанием клавиатуры. Мы не будем сейчас перечислять эти функции, они будут подробно описаны в главе, посвященной клавиатуре. С помощью функций обслуживания клавиатуры можно выполнить ввод кода нажатой клавиши как с ожиданием нажатия, так и без ожидания. В последнем случае функция сразу после вызова возвращает код нажатой клавиши или признак того, что никакая клавиша не нажималась.

Заметим, что символы, введенные с клавиатуры, помещаются в специальный клавиатурный буфер. Функция ввода символа без ожидания нажатия на клавишу проверяет состояние буфера — есть в нем символы, или нет. Если в буфере есть символы, первый помещенный в буфер символ возвращается программе. Этот символ затем может быть считан функцией ввода с ожиданием нажатия — фактически ожидания при этом не будет.

Для очистки буфера клавиатуры также можно использовать пару описанных выше функций: сначала программа проверяет пуст ли буфер, и, если он не пуст, считывает символ. Считанный символ никуда не помещается (теряется). После считывания символа программа опять проверяет содержимое буфера и так до тех пор, пока клавиатурный буфер не окажется пустым.

Для машин класса не ниже AT обработчик прерывания INT 16h выполняет и другие функции: установку задержки, запись символов в буфер клавиатуры, обслуживание расширенной клавиатуры.

Обслуживание дисковой подсистемы.

Прерывание INT 13h предназначено для обслуживания жестких и флоппи-дисков. Многочисленные функции прерывания INT 13h выполняют все операции по вводу/выводу на диски. Мы сделаем обзор только самых важных функций, остальные будут рассмотрены в книге 3, посвященной файловой системе.

00h — Сброс дисковой системы.

Эта функция выполняет установку в исходное состояние всей дисковой системы или выбранного дискового устройства. Используется обычно перед началом работы с устройством.

01h — Получить состояние дисковой системы.

Эта функция позволяет проверить результат выполнения предыдущей операции. Если операция завершилась аварийно, при помощи этой функции можно определить код ошибки.

02h/03h — Чтение/запись секторов.

Выполняется чтение секторов в оперативную память компьютера или запись информации из памяти в сектора диска.

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

04h — Проверка секторов.

Функция проверяет сектора на правильность циклической контрольной суммы, CRC (Cyclic Redundancy Check); записи содержимого секторов в память не происходит.

Другие функции прерывания INT 13h.

Среди других функций прерывания INT 13h — форматирование дорожки, позиционирование головки на заданную дорожку диска, тестирование и предварительная установка диска, запуск диагностики контроллера и многое другое. Описание этих функций мы отложим до глав, посвященных файловой системе.

Вывод на принтер (параллельный порт).

BIOS содержит простейшую поддержку принтера — три функции прерывания INT 17h. Это функция 01h — инициализация принтера, 02h — опрос состояния принтера и 00h — вывод символа на принтер.

Поскольку к персональному компьютеру можно подключить несколько последовательных портов, при обращении к принтеру следует указывать номер порта.

Обслуживание последовательного порта связи

Функции прерывания INT 14h обслуживают порт последовательной передачи данных RS232. С помощью этих функций можно задавать формат и скорость передачи данных, определять состояние портов и, конечно, выполнять побайтную передачу данных.

Работа с системными часами.

Функции прерывания INT 1Ah обслуживают часы, имеющиеся в каждом компьютере. С их помощью вы можете установить время и дату, опросить текущее состояние часов. Вы можете работать с часами реального времени, которые имеются на машинах класса не ниже AT.

Для AT можно установить на заданное время «будильник» — в нужный момент будет вызвано прерывание «будильника» с номером 4Ah. Обработчик прерывания INT 4Ah может подать звуковой сигнал или вывести на экран предупреждающее сообщение.

Перезагрузка операционной системы.

Вызов прикладной программой прерывания INT 19h приведет к перезагрузке операционной системы.

Системный сервис для машин класса AT.

Прерывание INT 15h использовалось в компьютерах IBM PC и IBM PC Jr для управления кассетным накопителем на магнитной ленте (функции 0-3). Для машин класса AT и более высокого класса прерывание INT 15h имеет и другое назначение. С его помощью обслуживается расширенная клавиатура, выполняется программная задержка, задаваемая в микросекундах, обслуживается расширенная память. Кроме того, одна из функций прерывания INT 15h переводит процессор 80286 или 80386 в защищенный режим. Заметим, что вернуть процессор обратно в реальный режим можно только сигналом начального сброса. Это же относится и к арифметическому сопроцессору 80287.

Функция C0h прерывания INT 15h выдает дополнительные сведения о конфигурации аппаратных средств компьютера.

Для PS/2 назначение некоторых функций этого прерывания другое по сравнению с машиной AT.

На этом мы завершим описание предоставляемых BIOS функций и перейдем к обзору функций DOS.

DOS предоставляет программе набор системных вызовов, реализованных с использованием механизма программных прерываний. Эти вызовы открывают прикладной программе доступ к системной информации, к системе консольного ввода/вывода, файловой системе, к подсистеме управления программами и памятью, позволяют организовать обращение к драйверам устройств ввода/вывода и т.д.

Все основные функции DOS вызываются с помощью прерывания INT 21h, однако DOS использует и другие прерывания:

INT 20h завершение работы программы;
INT 25h/26h чтение/запись на диск с абсолютной адресацией секторов;
INT 27h завершение работы программы с оставлением ее резидентной в памяти;
INT 28h прерывание зарезервировано для DOS, может быть использовано для составления резидентных программ;
INT 2Eh выполнение команды DOS;
INT 2Fh прерывание мультиплексора, используется для спулера печати PRINT.COM.

Функции прерывания INT 21h можно разделить на следующие группы:

  • получение системной информации;
  • символьный ввод/вывод;
  • работа с файловой системой;
  • управление программами;
  • управление памятью;
  • связь с драйверами устройств;
  • прочий системный сервис.

В данном обзоре мы кратко рассмотрим эти группы, делая акцент в основном на составе функций. Полностью информация об использовании функций прерывания DOS INT 21h (и других прерываний DOS) будет приводиться в соответствующих разделах книги.

Номер функции задается при вызове прерывания INT 21h в регистре AH.

Получение системной информации.

Функция 30h возвращает в регистре AX номер версии DOS. Например, для версии MS-DOS 5.00 содержимое регистра AH равно 00, регистра AL — 05.

Дополнительно через регистр BH функция возвращает программе серийный номер фирмы-производителя ОЕМ (IBM — 00, DEC — 16h, 0FFh — Microsoft и т.п.), а в регистрах BL:CX после вызова функции находится серийный номер пользователя.

Эта информация может применяться для анализа возможности использования таких средств операционной системы, которые поддерживаются не всеми версиями DOS, или для настройки программы на конкретный серийный номер пользователя.

Функции 2Ah и 2Ch позволяют программе узнать системную дату и время.

Есть функции, возвращающие текущий диск и текущий каталог. Номера этих функций — 19h и 47h.

Функция 2Fh позволяет программе узнать адрес текущей области DTA (Disk Transfer Area). Эта область используется, например, при поиске файлов в каталоге.

Важная информация находится в блоке PSP (Programm Segment Prefix). Этот блок располагается в памяти непосредственно перед выполняющейся программой. В нем находятся, в частности, параметры, передаваемые программе при запуске. Функция 62h возвращает адрес текущего блока PSP.

Кратко перечислим некоторые другие функции для получения системной информации:

35h получить значение вектора прерывания с заданным номером;
4Dh узнать код завершения процесса;
59h получить расширенный код ошибки;
54h узнать, используется ли проверка при записи на диск;
33h узнать, используется ли проверка на CTRL-BREAK.

Символьный ввод/вывод.

Эти функции применяются для работы со всеми символьными устройствами, такими как консоль, принтер, последовательный порт, и называются функциями стандартного ввода/вывода.

Ввод/вывод программы, использующей стандартные функции, может быть переназначен.

Приведем обзор основных функций стандартного символьного ввода/вывод в виде таблицы:

Код Назначение Описание
01h Ввод с клавиатуры Выполняется ввод символа со стандартного ввода и эхо-вывод символа на стандартное устройство вывода. Выполняется проверка на нажатие комбинации клавиш CTRL/C и CTRL-BREAK
06h Ввод с клавиатуры Ввод символа со стандартного ввода без ожидания и вывод его на устройство стандартного вывода. Комбинации CTRL/C и CTRL-BREAK не проверяются.
07h Прямой ввод Ввод символа со стандартного с клавиатуры устройства ввода. Комбинации клавиш CTRL/C и CTRL-BREAK не проверяются.
08h Ввод с клавиатуры Аналогично функции 07h, но проверяются комбинации клавиш CTRL/C и CTRL-BREAK.
02h Отобразить символ Отображаемый символ посылается на стандартное устройство вывода.
09h Отобразить строку На стандартное устройство вывода символов посылается строка, закрытая символом ‘$’.
03h Ввод из последовательного порта Вводится символ из последовательного порта
04h Вывод в последовательный порт Выводится символ на последовательный порт
05h Вывод на принтер Выводится символ на принтер.

Из таблицы видно, что для ввода с клавиатуры можно использовать несколько функций. Ввод без эхо-вывода удобен для такой информации, как пароли. Если логика работы программы не допускает прерывания по нажатию комбинаций клавиш CTRL-C или CTRL-BREAK, нужно использовать функции, которые не проверяют эти комбинации.

Для вывода строки символов можно использовать функцию 09h, но выводимая строка не может содержать символ ‘$’, так как этот символ используется в качестве признака конца строки.

Работа с файловой системой.

DOS предоставляет программам обширный сервис для работы с файлами и дисками. Практически все файловые операции можно выполнять с помощью специально предназначенных для этого функций, только в некоторых случаях (защита данных от копирования, например) приходится использовать прямое обращение к диску.

С помощью файловых функций DOS можно создавать и удалять файлы и каталоги, открывать и закрывать файлы, создавать временные файлы. Ввод/вывод может быть буферизован, можно получить как последовательный доступ к содержимому файла, так и произвольный.

Мы не будем приводить сейчас конкретные примеры или номера функций, отложим это до книги 3, посвященной файловой системе.

Управление программами.

DOS предоставляет программам возможность организовать запуск других программ или загрузку и выполнение программных оверлеев. Для этого служит функция 4Bh.

Для завершения работы программа должна также использовать одну из специальных функций DOS. Функция 4Ch, завершая работу программы, позволяет передать операционной системе некоторое число, называемое кодом завершения программы. Это число может быть затем проанализировано в пакетном файле командой IF ERRORLEVEL. Если одна программа запускает другую, то первая может получить код завершения второй с помощью функции 4Dh.

Для того чтобы завершающаяся программа осталась в оперативной памяти (т.е. стала резидентной), она должна вызвать прерывание INT 27h или воспользоваться функцией 31h.

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

Управление памятью.

DOS управляет распределением памяти с помощью блоков управления памятью MCB (Memory Control Block). Вся память разбивается на блоки различного размера, которым предшествует блок MCB, содержащий характеристики данного блока памяти (например, его размер).

Программа может динамически получать и освобождать области памяти с помощью функций 48h и 49h соответственно. Кроме того, можно изменять размер блока, выделенного операционной системой программе. Это делает функция 4Ah.

Детально механизм управления памятью будет рассмотрен в главе 2 при описании векторной таблицы связи DOS.

Связь с драйверами устройств.

Мы уже обращали Ваше внимание на то, что программы не могут обращаться непосредственно к драйверам устройств ввода/вывода. Все обращения к драйверам имеют либо неявный характер (ввод/вывод с помощью функций прерывания INT 21h), либо используют специальную функцию DOS с кодом 44h. Эта функция используется для обмена управляющей информацией между драйвером и программой.

Другие функции.

Существуют функции, позволяющие переопределять прерывания, работать с системными часами и календарем, функции для работы в сети и некоторые другие. Эти функции будут описаны позже в соответствующих разделах книги.

Когда программа обращается к DOS для выполнения какой-либо операции, она должна вызвать соответствующее прерывание, загрузив перед вызовом прерывания все необходимые операнды в регистры процессора. Если выполнение операции невозможно по каким-то причинам (неправильные операнды, устройство неработоспособно, запрашиваемая операция не поддерживается текущей версией DOS и т.д.), то для большинства функций DOS устанавливается признак ошибки — флаг переноса CARRY. Для DOS версии 2.0 и более поздних версий регистр AX при этом содержит код ошибки.

Приведем коды ошибок, возвращаемые программе через регистр AX:

1 Неправильный код функции
2 Файл не найден
3 Путь не найден
4 Слишком много открытых файлов
5 Доступ запрещен
6 Неправильный идентификатор файла
7 Разрушен блок управления памятью
8 Недостаточно памяти
9 Неправильный адрес блока памяти
10 Неправильная среда
11 Неправильный формат
12 Неправильный код доступа
13 Неправильные данные
14 Зарезервировано
15 Ошибка при указании дисковода
16 Невозможно удалить текущий каталог
17 Другое устройство
18 Больше нет подходящих файлов

Для DOS версии 3.0 и более поздних версий обработка ошибок значительно расширена. Введена функция 59h прерывания INT 21h, предназначенная для получения дополнительной информации об ошибках.

При вызове этой функции регистр BX должен содержать индикатор уровня анализа ошибок, который должен быть равен 0. Кроме расширенного кода ошибки, возвращаемого в регистре AX, программа может получить класс ошибки (регистр BH), код предполагаемых действий (регистр BL), локализацию ошибки, т.е. место, где произошла ошибка (регистр CH).

К сожалению, эта функция разрушает содержимое регистров CL, DX, SI, DI, BP, DS, ES. Программа, использующая функцию 59h, должна позаботиться о сохранении содержимого этих регистров.

Расширенный код ошибки, возвращаемый в регистре AX, может принимать значения, указанные в приводимой ниже таблице. Коды от 1 до 18 эквивалентны представленным выше и второй раз не приводятся.

Расширенные коды ошибок:

19 Запись на защищенный от записи диск
20 Задан неизвестный идентификатор устройства
21 Дисковод не готов
22 Неизвестная команда
23 Ошибка циклического кода проверки
24 Неправильная длина структуры запроса
25 Ошибка поиска
26 Неизвестен тип среды носителя данных
27 Сектор не найден
28 Кончилась бумага в принтере
29 Ошибка записи
30 Ошибка чтения
31 Общая ошибка
32 Нарушение разделения файла
33 Нарушение блокировки файла
34 Неправильная замена диска
35 FCB недоступен (слишком много блоков FCB)
36 Переполнился буфер разделения
37 Зарезервировано
38 Не завершена операция «Конец файла»
39-49 Зарезервировано
50 Сетевая функция не поддерживается
51 Удаленный компьютер «не слышит»
52 Дублирование имени в сети
53 Сетевое имя не найдено
54 Сеть занята
55 Сетевое устройство больше не существует
56 Превышен лимит команды сетевой BIOS
57 Ошибка в аппаратуре сетевого адаптера
58 Неправильный ответ из сети
59 Непредусмотренная ошибка сети
60 Несовместимый удаленный адаптер
61 Заполнена очередь печати
62 Для печатаемого файла недостаточно места
63 Печатающийся файл был удален
64 Сетевое имя было удалено
65 Доступ запрещен
66 Неправильный тип сетевого устройства
67 Сетевое имя не найдено
68 Превышен лимит сетевого имени
69 Превышен лимит сеанса сетевой BIOS
70 Временная пауза
71 Сетевой запрос отвергнут
72 Приостановлена печать или переадресация диска
73-79 Зарезервировано
80 Файл уже существует
81 Зарезервировано
82 Невозможно создать дескриптор в каталоге
83 Ошибка обработчика критических ошибок INT 24h
84 Слишком много переназначений
85 Двойное переназначение
86 Неправильный пароль
87 Неправильный параметр
88 Ошибка данных в сети
89 Нет такой функции в сети
90 Требуемый компонент системы не установлен

Класс ошибки, передаваемый в регистре BH, содержит информацию, которая поможет вам обработать данную ошибку:

1 Недостаточно ресурсов: блоков FCB, памяти и т.д.
2 Временная ситуация
3 Нет прав доступа
4 Внутренняя ошибка DOS
5 Ошибка аппаратуры
6 Системная ошибка DOS (нет CONFIG.SYS и т.п.)
7 Ошибка в прикладной программе
8 Файл или объект не найден
9 Неправильный формат файла или объекта
10 Файл или объект заблокирован
11 Ошибка носителя данных
12 Файл или объект уже существует
13 Прочие ошибки

Код предполагаемых действий, передаваемый через регистр BL, поможет Вашей программе правильно обработать ошибку и избежать зависания системы. Приведем таблицу кодов предполагаемых действий:

1 Повторить операцию позже. Можно спросить пользователя, желает он повторить операцию или завершить работу программы.
2 Повторить предыдущую операцию после небольшой паузы. Если ошибка не исчезла, следует спросить пользователя, будет он ждать и дальше, или следует завершить работу программы.
3 Если пользователь вводил какие-то данные для DOS, следует попросить его ввести эти данные еще раз (например, пользователь мог указать неправильный идентификатор диска или путь доступа к файлу).
4 Аварийно завершить работу прикладной программы с выполнением всех обычных завершающих действий (закрытие файлов, сброс буферов на диск, освобождение блоков памяти и т.д.)
5 Немедленный выход из программы без выполнения завершающих действий. Система находится в непредсказуемом состоянии.
6 Следует игнорировать ошибку.
7 Повторить операцию после того, как пользователь выполнит требуемые действия (установит дискету и т.п.).

Сведения о локализации ошибки передаются в регистре CH. Приведем таблицу кодов локализации:

1 Локализация ошибки не может быть определена (система не знает, где произошла ошибка).
2 Ошибка произошла в блочном устройстве (диск или магнитная лента).
3 Ошибка связана с сетью.
4 Ошибка произошла в символьном устройстве, например, в принтере.
5 Ошибка связана с оперативной памятью.

Если Ваша программа составлена на языке ассемблера, то после обращения к DOS через прерывание следует проверить состояние флага переноса:

Программы, составленные на языке Си, обращаются к прерываниям DOS обычно с помощью таких функций, как intdos, int86, intdosx и т.д. Для передачи параметров используются структуры REGS, WORDREGS, BYTEREGS, SREGS. Они описаны в файле dos.h, для использования этих структур программа должна содержать строку:

Значение флага переноса записывается в переменную cflag, определенную в структуре WORDREGS. Эта структура входит в объединение REGS:

Проверка переменной cflag может быть выполнена, например, таким образом:

Код ошибки при этом содержится в переменной outregs.x.ax.

Приведем пример программы, которая стирает каталог с именем DIR в текущем каталоге и, в случае ошибки, выводит расширенную информацию об ошибке, класс ошибки, код предполагаемых действий и код локализации ошибки:

При составлении программ обработки ошибок следует учитывать, что для DOS версии 1.0 при некоторых ошибках функции DOS возвращают в регистре AX значение 0FFh. Начиная с версии DOS 2.0, при ошибке устанавливается флаг переноса, код ошибки записывается в регистр AX. Однако для более полной диагностики причины ошибки следует использовать функцию 59h прерывания INT 21h.

Если Ваша программа, составленная на языке Си, вызывает функции DOS неявным образом (через функции стандартной библиотеки транслятора, такие как fprintf, puts и т.д.), то можно воспользоваться средствами обработки ошибок, входящими в состав стандартной библиотеки.

Когда при обращении к функциям DOS средствами стандартной библиотеки транслятора Си возникает ошибка, то в глобальную переменную errno записывается код ошибки.

Возможны следующие коды ошибок (они описаны в файле errno.h и stdlib.h):

ECHILD Нет порожденных процессов. Задача, не имеющая подзадач, выдала команду ожидания, или была выдана команда ожидания для подзадачи, имеющей признак NO-WAIT.
EAGAIN Больше нет процессов. Попытка создать новый процесс окончилась неудачно, т.к. либо больше нет резервов для создания процессов, либо недостаточно оперативной памяти, либо превышен максимальный уровень вложенности процессов.
E2BIG Слишком велик список аргументов. Либо размер списка аргументов превышает 128 байт, либо требуемый размер памяти для среды превышает 32К.
EACCES Доступ запрещен. Затребованный вид доступа к файлу запрещен или несовместим с установленными атрибутами файла (или каталога). Этот код ошибки передается при попытке чтения из неоткрытого файла, при попытке записи в файл, защищенный от записи, или при попытке открыть каталог как файл.
EBADF Плохой номер файла. Номер файла, использованный при вызове функции, имеет неверное значение или не относится к открытому файлу, или сделана попытка записи в открытый только для чтения файл или устройство.
EDEADLOCK Произошла блокировка ресурсов. Произведено 10 неудачных попыток заблокировать файл. Этот код ошибки используется только DOS версии 3.0 и более поздних версий.
EDOM Ошибка в аргументе математической функции. Аргумент математической функции вышел за пределы области определения этой функции.
EEXIST Файл уже существует. Сделана попытка создать файл с именем, которое уже используется существующим файлом.
EINVAL Неверный аргумент. Для одного из аргументов функции было задано неверное значение.
EMFILE Открыто слишком много файлов. Исчерпан запас номеров файлов , нельзя больше открыть ни одного файла.
ENOENT Нет такого файла или каталога. Запрошенный файл или каталог отсутствует или не может быть найден.
ENOEXEC Сделана попытка выполнить загрузочный файл, имеющий неправильный формат.
ENOMEM Недостаточно памяти. Эта ошибка появляется, когда недостаточно памяти для запуска процесса или для удовлетворения запроса программы на выделение блока памяти.
ENOSPC Нет свободного места на устройстве. На устройстве нет места для записи информации (например, переполнился диск).
ERANGE Слишком большой результат. Слишком большой по величине аргумент математической функции привел к частичной или полной потере значимости результата.
EXDEV Связь различных устройств. Сделана попытка переслать файл на другое устройство, используя функцию переименования.

Из приведенного выше списка кодов ошибок видно, что средствами стандартной библиотеки транслятора обрабатываются не только ошибки, возникающие при обращении к функциям DOS, но и ошибки, появляющиеся при работе с математическим функциями.

Для диагностической выдачи сообщения об ошибке можно использовать функции perror и strerror. Первая функция выводит в stderr соответствующее сообщение об ошибке, вторая только формирует строку сообщения. Функции perror и strerror имеют операнд — указатель на строку. Эта строка добавляется в начало стандартного сообщения об ошибке. Если к стандартному сообщению ничего добавлять не надо, операнд должен иметь значение NULL.

Следует заметить, что значение переменной errno отражает последнюю ошибку. Успешный вызов функции не приводит к автоматическому сбросу переменной errno.

Поэтому функции perror и strerror необходимо вызывать сразу после того, как вызываемая функция возвратит признак ошибки.

Приведем пример программы, обрабатывающей ошибки с использованием переменной errno:

DOS имеет еще одно средство для обработки ошибок — обработчик критических ошибок (Critical Error Handler). Этот модуль вызывается DOS, когда она получает сообщение об ошибке от драйвера устройства.

Модуль выдает на экран хорошо известное вам сообщение:

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

Обработка символьной информации с помощью функций DOS

Прерыванием (interrupt),подробнее см. раздел 7, называется способ общения центрального процессора с периферийными устройствами. Периферийное устройство (клавиатура, дисковод и др.) посылает запрос на установление сеанса передачи, процессор прерывает выполнение основной программы и переходит на выполнение программы обработки запроса от периферийного устройства. Эта программа, драйвер устройства, предварительно загружена в память (резидентная программа) и её адрес известен процессору. Такая обработка запросов называется аппаратными прерываниями.

Программные прерывания и системные вызовы

Операционная система MS_DOS, как известно, является однозадачной операционной системой, т.е. одновременно может исполнять только одну задачу. Вместе с тем имеется необходимость во время выполнения основной задачи производить некоторые вспомогательные действия. Подход, основанный на предварительной загрузке резидентных программ, использованный в аппаратных прерываниях, которые можно вызывать в момент выполнения основной программы, например, переключение раскладки клавиатуры или обращение к дисководу, оказался очень продуктивным, так как делает MS-DOS псевдомногозадачной системой.

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

Команда вызова программного прерывания имеет вид

int

— число, обычно в шестнадцатеричное, в диапазоне 00h – 0FFh, определяет адрес вызываемой резидентной программы.

Некоторые резидентные программы, выполняющие низкоуровневое общение с периферийными устройствами записаны в ROM BIOS (Read Only Memory Base Input/Output System) и поставляются вместе с системной платой, например, учёт системного времени, форматирование секторов на дорожке диска и т.д., и не зависят от применяемой операционной системы.

Резидентные программы, использующие низкоуровневую систему резидентов BIOS и выполняющие более сложные задачи, например, файловые операции с диском, подгружаются в память при загрузке операционной системы. Их принято называть функциями операционной системы или системными вызовами.

Наибольшее число различных системных функций в MS-DOS сосредоточено в резидентной программе с номером прерывания 21h – диспетчер функций MS-DOS. В зависимости от значения, содержащегося при вызове прерывания в регистре ah, MS-DOS выполняет одну из нескольких десятков функций MS-DOS.

Все функции BIOS и DOS описаны в специальных справочниках с указанием для каждой функции набора входных и выходных параметров, передаваемых через регистры, а также перечнем возможных ошибок. В данной главе будут описаны функции прерывания 21h относящиеся к работе с клавиатурой и экраном ПЭВМ.

Описание функций работы с клавиатурой и дисплеем диспетчера функций MS-DOS

Для вызова функции прерывания DOS 21h необходимо проделать следующие действия:

· выбрать функцию, выполняющую требуемые действия;

· занести номер функции в регистр аh;

· подготовить другие регистры (если это необходимо);

· написать команду int 21h;

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

Ниже следует описание некоторых функций 21Н.

Функции 01Н

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

аl = код ASCII введенного символа

· Примечание. Введенный символ отобращается на экране (выполняется эхо-отображение). Комбинация клавиш Ctrl/С (или Ctrl/Break) прекращает выполнение программ пользователя.

Функции 02Н

Выполняет отображение символа на стандартный вывод (дисплей).

dl = отображаемый символ

· Примечание. Символ отображается на стандартный вывод. Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программ пользователя.

Функция 05Н

Выполняет отображение символа на принтер.

dl = символ для принтера

· Примечание. Символ отображается на принтер. Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программ пользователя. Эта функция не возвращает ошибки состяния принтера.

Функция 07Н

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

al = код ASCIL введенного символа

· Примечание. Введенный символ не отображается на экране (не выполняется эхо-отображения). Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программы пользователя.

Функция 08Н

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

al = код ASCII введенного символа

· Примечание. Введенный символ не отображается на экране (не выполняется эхо-отображение). Комбинация клавиш Ctrl/C ( или Ctrl/Break) прекращает выполнение программы пользователя.

Функция 09Н

Выполняет отображение строки на стандартный вывод.

ds: dx=указатель на отображаемую строку

· Примечание: Строка отображается на стандартный вывод. $ признак конца строки, $ не отображается, dx содержит смещение строки, ds — сегментный адрес. Ниже приведены код управления курсором:

0dh (13) — перевод курсора в начало текущей строки;

0ah (10) — перевод курсора вниз на 1 строку;

08h (8) — перевод влево на 1 позицию;

Чтобы вывести на экран с новой строки текст: “Функция 09Н для

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

строку, следует в сегменте данных описать строку:

beg db 0dh, 0ah, “Функция 09Н для выдачи текста наэкран”, 0dh,0ah, “$”

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

lea dx,beg ; адрес строки в dx

mov ah,09h ; номер функции в аh

int 21h ; вызов функции

Функция ОАН

Выполняет ввод с клавиатуры в буфер строки символов.

ds: dx = адрес буфера ввода

Строка символов по указанному адресу

· Примечание. Читается со стандартного ввода. dx содержит смещение буфер вывода, DS — сегментный адрес. Буфер вывода имеет следующую структуру: 0-й байт содержит максимальное количество символов в буфере; 1-й байт содержит количество реально введенных символов; начиная со 2-го размещён буфер для ввода размером не менее указанного в в 1-м байте. Выполняется эхо-отображение. Комбинация клавиш Ctrl/C (или Ctrl/Break) прекращает выполнение программы пользователя. Символы вводятся один за другим, до тех пор, пока не будет введен код ODh (код клавиш “Enter”), завершающий строку. В ходе ввода строки пользователь может редактировать строку, и, в частности, использовать “забой”.

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

buffer db 11 ; Нулевой байт буфера

entered db (?) ; Число введенных символов

string db 11 dup (?) ; Введенные символы

Сам ввод выполняется командами:

lea dx, buffer ; Адрес буфера в dx

mov ah, 0ah ; Номер функции в аh

int 21h ; Вызов функции

Функция 0Bh

Выполняет опрос состояния буфера клавиатуры.

аl = 00h, если нет символа в буфере клавпиатуры;

al = ffh, если есть символ в буфере клавиатуры.

· Примечание. Устанавливает значение AL в зависимости от наличия символов в буфере клавиатуры. Часто используются в задачах, действующих при нажатии определенных клавиш. Комбинация клавиш Ctrl/ (или Ctrl/Break) прекращает выполнение программы пользователя.

Пример выполнения работы

Ввести строку с клавиатуры, посчитать, сколько и каких десятичных цифр имеется во введенной строке, посчитанные значения вывести на терминал.

COUNT db 10 dup (0) ; счетчик количества цифр

CIFR db ‘0123456789ABCDEF’ ; таблица преобразования цифр

IN_STR db 80, ?, 82 dup (?) ; буфер ввода

OUT_STR db 0Dh, 0Ah, ?,’-‘. ?,’$’ ; буфер вывода

assume cs:code, ds:data

START: mov ax, data

mov ds, ax ; Загрузить сегментный адрес данных

xor ah, ah ; обнуление старшего байта AX

lea bx, IN_STR+2 ; адрес начала введённой строки

mov cl, IN_STR+1 ; количество введенных символов

ВВ: mov al, [BX] ; очередной символ строки

cmp al,’0’ ; код символа меньше чем код нуля?

jb NC ; да, не цифра

cmp al, ‘9’ ; код символа больше чем код девяти

ja NC ; да, не цифра

; символ — десятичная цифра

sub al, ‘0’ ; преобразуем ASCII код в число

mov si, ax ; индекс в массиве счетчиков COUNT

inc COUNT[si] ; увеличиваем счетчик цифр

NC: inc bx ; получить очередной символ строки

lea bx, CIFR ; адрес таблицы преобразования цифр в ASCII

xor si, si ; номер выводимой цифры

add ax, si ; ASCII код очередной цифры с номером в si

mov OUT_STR+2, al ; в буфер вывода

mov dl, COUNT[si] ; читать количество цифр с номером в si

push cx ;временное сохранение cx

mov cl, 4 ; сдвиг на четыре

shr al, cl ; выделить старшую цифру

xlat ; ASCII старшей цифры в al

pop cx ; восстановление cx

mov OUT_STR+4, al ; в буфер вывода

mov al, dl ; восстановить количество цифр в al

and al,00001111b ; выделить младшую цифру

xlat ; ASCII младшей цифры в al

mov OUT_STR+5, al ; в буфер вывода

lea dx, OUT_STR ; подготовка к выводу строки

mov ah, 09h ; номер функции

int 21h ; вывод строки

inc si ; Счетчик очередной цифры

QUIT: mov ax, 4C00h ; Код завершения 0

int 21h ; Выход в DOS

Варианты заданий

Ввести с клавиатуры строку. Сжать строку, т.е. удалить пробелы и табуляции. Вывести результаты на экран.

Ввести с клавиатуры строку. Преобразовать все малые буквы в боль­шие. Вывести результаты на экран.

Ввести с клавиатуры строку. Посчитать количество слов в строке. Определить, что является разделителем слов. Вывести результаты на экран.

Ввести с клавиатуры строку. Ввести с клавиатуры коротенькую строку — шаблон. Найти шаблон во введенной строке. Вывести на экран “ДА”, если шаблон есть и “НЕТ”, если нет.

Ввести с клавиатуры две строки. Сравнить их. Вывести на экран “ДА”, если они равны и “НЕТ”, если нет.

Ввести с клавиатуры строку. Если она длиннее некоторой заданной величины, то обрезать, если короче растянуть, вставив нужное число пробелов между словами. Вывести результаты на экран.

Ввести с клавиатуры строку, состоящую из нескольких слов. Вывести каждое слово на экран в отдельной строке, т.е. выдать слова в столбик.

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

Ввести с клавиатуры две строки. Сравнить их. Вывести на экран номер начала второй строки в первой.

Ввести с клавиатуры строку, содержащую несколько точек. Преобразовать строку, чтобы после каждой точки был пробел, и следующая буква после точки были заглавная. Вывести результаты на экран.

Ввести с клавиатуры строку, содержащую несколько слов, разделенных пробелом. Переставить в ней слова, поменяв местами первое слово с последним, второе с предпоследним и т.д. Вывести результаты на экран.

Ввести с клавиатуры строку, состоящую из нескольких слов. Вывести каждое слово на экран в отдельной строке лесенкой, т.е. выдать каждое слово в столбик, с фиксированным сдвигом относительно начала предыдущего.

Ввести с клавиатуры строку. Преобразовать все буквы в числа. Построить криптограмму (вместо букв вывести на экран соответствующие им числа).

Ввести с клавиатуры строку, состоящую из нескольких букв. Заменить каждую букву в строке на другую букву, следующую за данной буквой по алфавиту. Вывести результаты на экран.

Ввести с клавиатуры строку и строку из двух чисел. Первое число указывает начало подстроки для ввода на экран, второе количество символов из первой строки, которое необходимо вывести на экран. Ввести с клавиатуры две строки. Сравнить их. Вывести на экран номер начала первой строки во второй. Ввести с клавиатуры строку. Ввести с клавиатуры коротенькую строку — шаблон. Найти шаблон во введенной строке. Вывести на экран “ДА”, если шаблон есть и “НЕТ”, если нет.

Ввести с клавиатуры две строки. Сравнить их. Вывести на экран какая из строк больше и насколько.

Ввести с клавиатуры строку и некоторое число. Если строка длиннее заданного числа, то обрезать, если короче растянуть, вставив нужное чис­ло пробелов между словами. Вывести результаты на экран.

Ввести с клавиатуры строку, состоящую из нескольких слов. Вывести каждое слово на экран в отдельной строке, со смещением влево на одно знакоместо по отношению к предыдущей строке.

Ввести с клавиатуры строку. Посчитать в ней количество запятых. Вывести результаты на экран.

Ввести с клавиатуры две строки. Вывести на экран все символы, которые содержатся в обеих строках.

Ввести с клавиатуры строку, содержащую несколько точек. Преобразовать строку, чтобы после каждой точки был пробел, и следующая буква после точки были заглавная. Вывести результаты на экран.

Ввести с клавиатуры строку, содержащую несколько слов, разделенных пробелом. Переставить в ней слова, поменяв местами первое слово с последним, второе с предпоследним и т.д. Вывести результаты на экран.

Ввести с клавиатуры строку, состоящую из нескольких слов. Вывести каждое слово на экран в отдельной строке лесенкой, т.е. выдать каждое слово в столбик, с заданным сдвигом относительно начала предыдущего.

Ввести с клавиатуры строку. Преобразовать все буквы в числа. Построить криптограмму (вместо букв вывести на экран соответствующие им числа).

Ввести с клавиатуры строку, состоящую из нескольких букв. Заменить каждую букву в строке на другую букву, следующую за данной буквой через заданное число символов по алфавиту. Вывести результаты на экран.

Вопросы по теме

Что такое программное прерывание?

Какие возможности работы с клавиатурой имеются у программиста?

Чем отличаются друг от друга различные функции DOS? выполняющие ввод с клавиатуры?

Как работает команда xlat?

Можно ли выдать на экран текст ‘$1.00=25,00 rub/’, используя функции DOS 09h?

Какие режимы адресации удобно использовать при работе с одномерными массивами?

Что означает выражения в поле операндов в строках примера

mov OUT_STR+3, al?

Как выделить младшую тетраду байта?

Как выделить старшую тетраду байта?

В чем отличие команд

mov BX, offset STR?

Подпрограммы

Подпрограммы позволяют сократить объём текста программы, применять модульный принцип построения программ, использовать одни и те же подпрограммы в различных программах, что значительно сокращает время создания программ и уменьшает время отладки.

Структура подпрограммы

· Описание подпрограммы в языке ассемблер имеет следующую структуру:

· proc

операторы тела подпрограммы

ret [ ]

endp

— определяет тип перехода: near (близкий), far (дальний). Если тип не задан, по умолчанию принимается near. Тип перехода near показывает, что тело процедуры описано в том же сегменте, что и её вызов. Тип перехода far обеспечивает вызов процедуры из других сегментов, с другим значением регистра CS. Такие процедуры обычно используются как отдельные объектные модули или в составе библиотек.

ret [ ] — выполняет возврат из процедуры в вызывающую программу. В зависимости от типа процедуры, эта команда восстанавливает из стека значение IP (ближний вызов) или CS:IP (дальний вызов). Эта команда не обязана быть последней по тексту процедуры, но является последней по порядку выполнения. Значение указывает размер стека в байтах, восстанавливаемого при возврате из процедуры. Восстановление стека необходимо производить при передаче параметров процедуры через стек. Так как работа со стеком выполняется словами, значение всегда должно быть кратным двум.

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

Вызов подпрограммы

· Вызов подпрограммы выполняется командой

call [ ptr]

near(word) или far(dword). Если тип не задан, по умолчанию принимается near.

— имя или адрес процедуры. При ближнем вызове в стеке запоминается текущее значение регистра IP. При дальнем вызове в стеке запоминаются значения CS:IP.

Если тип вызова не указан явно, он определяется типом, на который указывает , аналогично команде безусловного перехода jmp.

Пусть в сегменте данных описаны переменные:

в сегменте кода описаны подпрограммы:

FPROC proc far

FPROC endp

NPROC proc

NPROC endp

Рассмотрим различные примеры команд вызова:

call FPROC ;дальний вызов п/п FPROC

call FPROC ;дальний вызов п/п FPROC

call FADDR ;дальний вызов п/п, чей адрес в FADDR

call NADDR ;ближний вызов п/п, чей адрес в NADDR

call dx ; ближний вызов п/п, чей адрес в DX

call word ptr [BX] ; косвенный ближний вызов п/п

call dword ptr [BX] ; косвенный дальний вызов п/п

Передача параметров

· Для передачи входных параметров в подпрограмму и выходных в программу существует несколько способов. Чаше всего передача параметров осуществляется через регистры или через стек.

· При передаче через регистры перед вызовом подпрограммы параметры заносятся в регистры процессора, а после возврата вызывающая программа забирает из регистров значения результатов.

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

push src

Для обращения к параметрам, хранящимся в стеке, обычно используется регистр bp:

mov bp, sp

Необходимо помнить, что поверх параметров, передаваемых в подпрограмму, в стек записываются командой call одно или два слова адреса возврата. Каждая процедура «знает» свой тип вызова (одно или два слова) и отступив от верхушки стека на +2 или на +4 читает параметры.

mov ax, bp+2 ; первый параметр при ближнем вызове

mov ax, bp+4 ; первый параметр при дальнем вызове

Сохранение регистров

Подпрограмма во время выполнения использует регистры процессора. Значения, которые в них хранились, возможно, ещё понадобятся основной программе. По этой причине каждая подпрограмма обязана сохранить значения регистров перед началом их использования, а после завершения работы перед возвратом восстановить их прежние значения. Для сохранения регистров используется стек. В процессорах, начиная с 386, введены команды

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

Пример выполнения работы

· Разработать подпрограмму, которая удаляет, начиная с заданной позиции строки, указанного числа символов. Написать программу, которая вводит с клавиатуры строку, позицию и длину удаляемой части строки, удаляет указанную часть и выводит строку.

MESS1 db 0dh,0ah, «Введите строку:», 0dh,0ah, «$»

MESS2 db 0dh,0ah, «Введите позицию:», 0dh,0ah, «$»

MESS3 db 0dh,0ah, «Введите число удаляемых символов:», 0dh, 0ah, «$»

MESS4 db 0dh,0ah, «Строка после удаления:», 0dh,0ah, «$»

S_BUFLEN db 80 ; Максимальная длина строки

S_FACTLEN db ? ; Фактическая длина строки

S_INPBUF db 80 dup(?) ; Введённая строка

N_BUFLEN db 3 ; Максимальная длина числа при вводе

N_FACTLEN db ? ; Фактическая длина числа

N_INPBUF db 3 dup(?) ; Введённое число

POSDEL dw ? ; Позиция начала удаления

LENDEL dw ? ; Число удаляемых символов

assume cs:code, ds:data

START: mov ax, data

LOP: lea DX, MESS1

int 21h ;приглашение к вводу строки

lea DX, S_BUFLEN

int 21h ; ввод строки

mov AL, S_FACTLEN

cmp al, 0 ; строка пустая?

ja LLL0 ; нет продолжать

jmp quit ; закончить работу

LLL0: lea bx, S_INPBUF ; получить адрес начала строки

cbw ; получить длину в слове

add bx, ax ; адрес конца строки

mov byte ptr [bx], «$» ; записать признак конца строки

; Ввод позиции удаления

LLL1: lea dx, MESS2

int 21h ;Приглашение к вводу позиции удаления

lea dx, N_BUFLEN

int 21h ; ввод позиции удаления

call VAL ; вызов процедуры перевода в число

jc LLL1 ; ошибка, повторить ввод

jz LLL1 ; ошибка, повторить ввод

cmp AL, S_FACTLEN ; превышает длину строки?

jg LLL1 ; ошибка, повторить ввод

cbw ; расширить до слова

mov POSDEL, AX ; запомнить позицию удаления

; Ввод длины удаляемой части

LLL2: lea dx, MESS3

mov AH, 09h ; приглашение к вводу числа

int 21h ; удаляемых символов

lea dx, N_BUFLEN

int 21h ; ввод числа удаляемых символов

call VAL ; вызов процедуры перевода в число

jc LLL2 ; ошибка, повторить ввод

cbw ; расширить до слова

mov LENDEL, AX ; запомнить число удаляемых символов

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

lea bx, S_INPBUF

mov al, S_FACTLEN ; дополняем до слова

push ax ; 4-й параметр длина строки

push LENDEL ; 3й параметр число удаляемых симв.

push POSDEL ; 2-й параметр позиция удаления

push bx ; 1й параметр адрес строки

call DELSUB ; вызов подпрограммы

int 21h ; вывод заголовка вывода

lea bx, S_FACTLEN

mov cl, S_FACTLEN

cmp byte ptr [bx], 0

loopne LLL3 ; повторять до конца строки или первого нуля

LLL4: mov byte ptr [bx], «$»

lea DX, S_INPBUF

QUIT: mov ax, 4c00h

; Функция получения числа из его строкового представления

; Схема преобразования десятичного числа а2а1а0 в 16-ричную СС по ;схеме Горнера — N16=(a2*A+a1)*A+a0 , где A десятичное основание

push bx ; сохранение

push cx ; регистров

push dx ; в стеке

lea bx, N_INPBUF ; адрес начала числа

mov cl, N_FACTLEN ; фактическая длина числа

xor ch, ch ; расширить до сх

mov dl, 10 ; основание системы счисления

VAL1: imul dl ; умножаем на основание

sub dh, «0» ; преобразуем его в цифру

add al, DH ; добавляем к результату

inc bx ; на следующий символ

clc ;сброс флага CF

stc ; если результат больше 255 установить флаг CF=1

VAL2: pop dx ; восстановить

pop cx ; регистры

pop bx ; из стека

; Подпрограмма удаления подстроки

;адрес строки BP+2, позиция удаления BP+4, число удаляемых символов ; BP+6, длина строки BP+8

DELSUB proc near

mov di, [bp+4] ; адрес начала строки

add di, [bp+6] ; адрес позиции удаления +1

dec di ; адрес позиции удаления

add si, [bp+8] ; адрес остающейся части строки

mov cx, [bp+4] ; адрес начала строки

add cx, [bp+10] ; адрес конца строки + «$»

sub cx, si ; число перемещаемых символов — 1

inc cx ; число перемещаемых символов

cld ; продвигаться от начала к концу

rep movsb ; переслать (cx) символов

pop cx ; восстановить

pop di ; регистры

ret 8 ; вернуться с очищением стека

Варианты заданий

· В приведённых ниже вариантах заданий способ передачи параметров в процедуру выбирать произвольно. Зациклить программу по вводу строки, а признаком окончания работы считать ввод пустой строки.

Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает содержится ли одна в другой и сколько раз.

Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и замещает первые буквы всех слов заглавными, а остальные строчными буквами.

Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строки до заданной длины (или дополняет пробелами, если длина строки меньше заданной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода пустая строка) и формирует новую строку, состоящую из первых N символов каждой введённой строки.

Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их в лексикографическом порядке.

Разработать подпрограмму, которая разбивает заданную строку на две части: первое слов (до первого пробела) и остальная часть строки (пробелы в начале строки убираются). Разработать программу, которая вводит с клавиатуры строку и выводит каждое слово с новой строки.

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

Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке и, если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает содержится ли одна в другой и сколько раз.

Разработать подпрограмму, которая подсчитывает, сколько раз заданный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку и число N и выдаёт список символов, которые встречаются в строке не менее N раз.

Разработать подпрограмму, которая преобразует заданное десятичное число в двоичную систему. Разработать программу, которая вводит с клавиатуры строку десятичных цифр и выводит на экран её эквивалент в двоичной системе. Если строка не является числом, то сообщает об этом.

Разработать подпрограмму, которая преобразует заданное шестнадцатеричное число в десятичную систему. Разработать программу, которая вводит с клавиатуры строку шестнадцатеричных цифр и выводит на экран её эквивалент в десятичной системе. Если строка не является числом, то сообщает об этом.

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

Разработать подпрограмму, которая разбивает заданную строку на слова (слово считается от пробела до пробела, но в состав слова не входят). Разработать программу, которая вводит с клавиатуры строку и выводит каждое слово с новой строки.

Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и заменяет первые буквы после точки на заглавные, а остальные на прописные.

Разработать подпрограмму, которая определяет, содержится ли одна строка в другой и если да то с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и определяет содержится ли вторая строка в первой и с какой позиции.

Разработать подпрограмму, которая каждой букве ставит в соответствие число равное её порядковому номеру в алфавите. Разработать программу, которая вводит с клавиатуры строку и выводит через пробел числа, кодирующие введённую строку символов.

Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает содержится ли одна в другой и сколько раз.

Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и замещает первые буквы всех слов заглавными, а остальные строчными буквами.

Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строки до заданной длины (или дополняет пробелами, если длина строки меньше заданной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода пустая строка) и формирует новую строку, состоящую из первых N символов каждой введённой строки.

Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обменивает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода пустая строка) и сортирует их в лексикографическом порядке.

Разработать подпрограмму, которая разбивает заданную строку на две части: первое слов (до первого пробела) и остальная часть строки (пробелы в начале строки убираются). Разработать программу, которая вводит с клавиатуры строку и выводит каждое слово с новой строки.

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

Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке и, если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает содержится ли одна в другой и сколько раз.

Разработать подпрограмму, которая подсчитывает, сколько раз заданный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку и число N и выдаёт список символов, которые встречаются в строке не менее N раз.

Разработать подпрограмму, которая преобразует заданное десятичное число в двоичную систему. Разработать программу, которая вводит с клавиатуры строку десятичных цифр и выводит на экран её эквивалент в двоичной системе. Если строка не является числом, то сообщает об этом.

Разработать подпрограмму, которая преобразует заданное шестнадцатеричное число в десятичную систему. Разработать программу, которая вводит с клавиатуры строку шестнадцатеричных цифр и выводит на экран её эквивалент в десятичной системе. Если строка не является числом, то сообщает об этом.

Вопросы по теме

Что такое “ближние” и “дальние” подпрограммы?

Как определить “ближний” или “дальний” вариант команды call использован в программе?

Какие способы используются для передачи параметров в подпрограммы?

Может ли массив быть параметром подпрограммы?

Можно ли использовать для чтения из стека параметров регистр sp вместо bp?

Что означает операнд команды ret?

Какой последовательностью команд можно заменить команду “ret 8”?

Обработка прерываний

· В MS-DOS различают аппаратные и программные прерывания. Первые возникают по запросу периферийных устройств. Вторые позволяют использовать предоставляемые системой MS-DOS и BIOS большой набор подпрограмм, выполняющих различные полезные действия и оформленные как программные прерывания. В некоторых случаях стандартные программы обработки как аппаратных, так и программных прерываний могут не удовлетворять программиста. Поэтому появляется необходимость заменить существующую программу обработки прерывания иной или внести новые функции в уже имеющуюся программу.

Обработка прерывания

Рассмотрим подробно действия, которые называются обработкой прерывания. Эти действия выполняются независимо от того вызвано ли прерывание аппаратно или программно. При получении сигнала на прерывание (при аппаратном прерывании от программируемого контроллера прерываний, при программном командой процессора int) процессор содержимое CS, IP и регистра флагов сохраняет в стеке. В CS и IP помещается адрес подпрограммы обработки прерывания, которая и выполняется, после чего восстанавливаются из стека содержимое CS, IP и регистра флагов, и процессор продолжает выполнение программы.

Двойное слово, в котором хранится адрес подпрограммы обработки прерывания, называется вектором прерывания. Всего допустимо иметь 256 различных векторов прерываний. Для хранения векторов прерываний в DOS выделен первый килобайт памяти. Адрес вектора прерывания с номером N вычисляется как N*4. В младшем слове хранится значение IP, а в старшем CS.

Пример. Определить адрес прерывания 21h. Получим 21h * 4h =84h. Просмотр содержимого четырёх байтов, начиная с 0084h в сегменте 0000h

Показывает, что там храниться число

где 0DDE – адрес сегмент, а 048B – адрес смещения подпрограммы обработки прерывания с номером 21h.

Если написать свою подпрограмму обработки прерывания и с помощью функций, описанных ниже, записать её адрес (сегмент и смещение) в вектор прерывания, то при вызове данного прерывания его обработка будет проходить по новой подпрограмме. Старый вектор прерывания, обычно, сохраняется и перед завершением программы восстанавливается.

Каждая подпрограмма обработки прерывания, в отличие от обычно подпрограммы, завершается командой iret, которая похожа на команду ret, но восстанавливает из стека кроме CS и IP ещё и регистр флагов.

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций.

Опора деревянной одностоечной и способы укрепление угловых опор: Опоры ВЛ — конструкции, предназначен­ные для поддерживания проводов на необходимой высоте над землей, водой.

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого.

indbooks

Читать онлайн книгу

Использование системных вызовов операционной системы MS-DOS

Функция Краткое описание
bdos вызов системы MS-DOS; используются только регистры DX и AL
dosexterr получение значений регистров из системы MS-DOS вызовом 59H
FP_OFF возвращает смещение far-указателя
FP_SEG возвращает сегмент far-указателя
int86 вызов прерывания MS-DOS
int86x вызов прерывания MS-DOS
intdos системный вызов MS-DOS
intdosx системный вызов MS-DOS
segread возвращает текущее значение сегментных регистров

Прототипы функций и макроопределения содержатся в файле dos.h.

Система программирования MSC предоставляет дополнительно функции:

Функция Краткое описание
inp чтение с указанного порта в/в
outp вывод в указанный порт в/в

Прототипы функций inp и outp содержатся в файле conio.h.

Система программирования ТС предоставляет дополнительно следующие функции:

Функция Краткое описание
absread чтение с диска по номеру сектора
abswrite запись на диск по номеру сектора
bdosptr вызов системы MS-DOS
country определение способа записи времени в данной стране
ctrlbrk установить реакцию на
disable отменить прерывания
enable разрешить прерывания
freemem освободить память
getinterrupt возбудить прерывание
getcbrk узнать установленную реакцию на
getdfree узнать объем свободного места на диске
getdta узнать адрес области передачи данных диска
getfat получить информацию из таблицы размещения файлов
getfatd получить информацию из таблицы размещения файлов
getpsp получить сегментный префикс для текущего программного адреса текущего выполняемого процесса
getvect узнать значение вектора прерывания
getverify узнать режим проверки записи на диск
harderr регистрация функции обработки аппаратных ошибок
hardresume возврат из функции обработки аппаратных ошибок
hardretn возврат из функции обработки аппаратных ошибок
inport ввести слово из порта
inportb ввести байт из порта
intr аналог функции int86
keep зафиксировать программу в памяти
MK_FP составить far-указатель из компонент
outport вывести слово в порт
outportb вывести байт в порт
parsfnm выделение имени файла из командной строки MS-DOS
peek получить значение слова по адресу
peekb получить значение байта по адресу
poke записать слово в память по адресу
pokeb записать байт в память по адресу
randbrd чтение с диска
randbwr запись на диск
setdta установить адрес области передачи данных диска
setvect задать значение вектора прерывания
setverify включить режим проверки записи на диск
sleep задержка
unlink удаление файла

Прототипы функций и макроопределения содержатся в файле dos.h.

Система программирования ТС предоставляет также следующие функции для обращения к BIOS (базовой подсистеме ввода/вывода операционной системы):

Основы программирования для ms-dos

Лабораторная работа № 2

Цели работы: изучить принципы программирования в ОС MS-DOS, научиться создавать EXE — и COM-программы, ознакомиться с основными функциями базовой системы ввода/вывода.

1 Программы типа COM

Файлы типа COM содержат только скомпилированный код без какой-либо дополнительной информации о программе. Весь код, данные и стек такой программы располагаются в одном сегменте и не могут превышать 64 Кбайт.

Рассмотрим типичный пример COM-программы:

.model tiny ;модель памяти, используется для COM

.code ;начало сегмента кода

org 100h ;начальное значение счетчика

mov ah, 9 ;номер функции DOS – в ah

mov dx, offset message ;адрес строки – в dx

int 21h ;вызов системной функции DOS

int 20h ;завершение COM-программы

Message db ‘Hello World!’, 13, 10, ‘$’;строка для

end start ;конец программы

Чтобы получить исполнимый файл, сначала вызываем ассемблер:

Tlink /t /x hello_1.obj

Рассмотрим исходный текст программы.

Модель памяти Tiny, в которой сегменты кода, данных и стека объединены, предназначена для создания файлов типа COM.

Org 100h устанавливает значение программного счетчика в 100h, так как при загрузке COM-файла в память DOS занимает первые 256 байт блоком данных PSP и располагает код программы только после этого блока. Все COM-программы должны начинаться с этой директивы.

Команда Mov ah, 9 помещает число 9 (номер функции DOS «вывод строки») в регистр AH.

Команда Mov dx, offset message помещает в регистр DX смещение метки MESSAGE относительно начала сегмента данных, который в нашем случае совпадает с сегментом кода.

Команда Int 21h вызывает системную функцию DOS с номером 9 (см. далее ).

Команда Int 20h используется для корректного завершения программы.

Следующая строка программы определяет строку данных «Hello World», управляющий символ ASCII «возврат каретки» (13), управляющий символ ASCII «перевод строки» (10) и символ «$», завершающий строку.

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

2 Программы типа EXE

EXE-программы немного сложнее в исполнении чем COM, но для них отсутствуют ограничения размера в 64 Кбайт. Рассмотрим пример EXE-программы:

message db ‘Hello world!’, 13, 10, ‘$’

mov ds, ax ;ds указывает на сегмент данных

mov ah, 9 ;функция печати строки DOS

mov dx, offset message ;dx указывает на Message

int 21h ;вывод на дисплей «Hello world!»

mov ah, 4ch ;функция завершения программы в DOS

int 21h ;завершить программу

В этом примере определяются три сегмента – сегмент стека, сегмент данных, содержащий строку, и сегмент кода.

При запуске EXE-программы регистр DS уже не содержит адреса сегмента со строкой Message (он указывает на сегмент, содержащий блок данных PSP), а для вызова функции DOS этот регистр должен иметь сегментный адрес строки. Команда Mov ax, @data загружает в AX адрес сегмента данных, а Mov ds, ax копирует его в DS. И наконец, программы типа EXE должны завершаться вызовом системной функции DOS с номером 4сh.

Tlink /x hello_2.obj

3 Прерывания базовой системы ввода/вывода

3.1 Понятие прерывания

В современных процессорах принят подход, основанный на понятии Прерывания. Прерывание – инициируемый определенным образом процесс, временно переключающий микропроцессор на выполнение другой программы с последующим возобновлением выполнения прерванной программы. Это позволяет обеспечить наиболее эффективное управление не только внешними устройствами, но и программами. Например, нажатие клавиши на клавиатуре инициирует немедленный вызов программы, которая распознает нажатую клавишу, заносит ее код в буфер клавиатуры, откуда он в дальнейшем считывается некоторой другой программой или операционной системой. На время такой обработки микропроцессор прекращает выполнение некоторой программы и переключается на так называемую Процедуру обработки прерывания. После того, как данная процедура выполнит необходимые действия, прерванная программа продолжит выполнение с точки, где было приостановлено ее выполнение.

Некоторые ОС используют механизм прерываний не только для обслуживания внешних устройств, но и для предоставления своих услуг. Так, ОС MS DOS взаимодействует с системными и прикладными программами преимущественно через систему прерываний.

Прерывания могут быть Внешними и Внутренними. Внешние вызываются внешними по отношению к микропроцессору событиями, а внутренние возникают внутри него во время вычислительного процесса. Одной из причин возбуждения внутреннего прерывания является обработка машинной команды Int xx, где Xx – номер прерывания. Такие прерывания называются программными.

Далее рассмотрим различные функции прерываний базовой системы ввода/вывода.

3.2 Вывод на экран в текстовом режиме

3.2.1 Вывод средствами DOS. В предыдущих примерах использовался один из способов вывода текста на экран – вызов функции DOS 09h. Это далеко не единственный способ вывода текста. Все функции вызываются через прерывание 21h:

Записать символ в STDOUT с проверкой на . Вход: AH = 02h; DL = ASCII-код символа. Обрабатываются управляющие символы: BEL (07h), BS (08h), HT (09h), LF (0Ah), CR (0Dh) и др. Если в ходе работы этой функции была нажата комбинация клавиш , вызывается прерывание 23h (по умолчанию – выход из программы);

Записать строку в STDOUT с проверкой на . Вход: AH = 09h; DS:DX = адрес строки, заканчивающейся символом «$». Действие этой функции полностью аналогично действию функции 02h, но выводится не один символ, а целая строка.

3.2.2 Вывод средствами BIOS. Функции DOS вывода на экран позволяют перенаправлять вывод в файл, но не позволяют вывести текст в любую позицию экрана и изменить цвет текста. BIOS (базовая система ввода/вывода) – это набор программ, расположенных в постоянной памяти компьютера и обеспечивающих доступ к некоторым устройствам, в частности к видеоадаптеру. Все функции видео-сервиса BIOS вызываются через прерывание 10h:

Установить видеорежим. Вход: AH = 00; AL = номер режима в младших 7 битах. Вызов этой функции приводит к тому, что экран переводится в выбранный режим. Если старший бит AL не установлен в 1, экран очищается. Номера режимов: 0, 1 – 16 цветов, 40х25; 2, 3 – 16 цветов, 80х25; 7 – монохромный режим, 80х25;

Установить положение курсора. Вход: AH = 02h; BH = номер страницы; DH = строка; DL = столбец. С помощью этой функции можно установить курсор в любую позицию экрана, и дальнейший вывод текста будет происходить из этой позиции. Символ в левой верхней позиции имеет координаты 0, 0;

Считать положение и размер курсора. Вход: AH = 03h; BH = номер страницы (каждая страница использует собственный независимый курсор). Выход: DH, DL = строка и столбец текущей позиции курсора; CH, CL = первая и последняя строки курсора;

Считать символ и атрибут символа в текущей позиции курсора. Вход: AH = 08h; BH = номер страницы. Выход: AH = атрибуты символа, изображенные на рисунке 3.1; AL = ASCII-код символа;

Вывести символ с заданным атрибутом на экран. Вход: AH = 09h;
BH = номер страницы; AL = ASCII-код символа; BL = атрибут символа;
CX = число повторений символа. С помощью этой функции можно вывести на экран любой символ, включая даже символы CR и LF, которые обычно интерпретируются как конец строки;

Вывести строку символов с заданными атрибутами. Вход: AH = 13h;
AL = режим вывода: бит 0 – переместить курсор в конец строки после вывода; бит 1 – строка содержит не только символы, но и атрибуты, так что каждый символ описывается двумя байтами: ASCII-код и атрибут; CX = длина строки (только число символов); BL = атрибут, если строка содержит только символы; DH, DL = строка и столбец, начиная с которых будет выводится строка;
ES:BP = адрес начала строки в памяти. Функция выводит на экран строку символов, интерпретируя управляющие символы CR, LF, BS и BEL.

Функции DOS вывода данных на экран

DOS предоставляет следующие способы вывода данных на экран:

использование функций Int 21h (02h, 06h, 09h), обеспечивающих посимвольный ввод с клавиатуры в разных режимах;

обращение к экрану, как к файлу, с помощью функции 40h.

¨ Функция 02h. Вывод одиночного символа.

Выводит символ, находящийся в регистре DL, на экран, после чего курсор сдвигается на одну позицию вправо. Для вывода строки функцию следует использовать в цикле. Допустимо перенаправление вывода. Выполняет обработку при вводе этой комбинации с клавиатуры перед выводом каждого 64-го символа. Эта функция выводит и управляющие ASCII-символы с кодами 07h, 08h, 09h, 0Ah, 0Dh. Символ с кодом 07h (bell, звонок) вызывает звуковой сигнал, с кодом 08h (backspace, забой) – возвращает курсор на одну позицию влево, с кодом 09h (tab, табуляция) – смещает курсор на одну позицию вправо, кратную 8. Действия управляющих клавиш с кодами 0Ah и 0Dh рассматривались ранее.

Вызов: AH = 02h, Int 21h.

Выход: DL = ASCII – код символа,

AL = код последнего записанного символа (кроме случая, когда DL = 09, тогда возвращается значение 20h).

Использование данной функции рассмотрим на примере процедуры перехода на новую строку.

mov ah,2 ;Запрос функции 02h

mov dl,13 ;Возврат каретки

int 21h ;Вызов DOS

mov dl,10 ;перевод строки

int 21h ;Второй вызов DOS

¨ Функция 09h.Вывод строки.

Выводит строку символов на устройство стандартного вывода (используется в системных программах для вывода на экран информационных сообщений). Строка должна заканчиваться символом $ (код 24h), который служит признаком конца строки, и сам не выводится. Допустимо перенаправление вывода. В сообщение могут быть включены и управляющие коды (07h, 08h, 09h, 0Ah, 0Dh), которые вызывают соответствующие им действия (см. функцию 02h). Допустимо использование Exc-последовательностей. Функция выполняет обработку при вводе этой комбинации с клавиатуры перед выводом каждого 64-го символа.

lea dx,[Promt] ;Адрес строки Promt: DS:DX

mov ah,09h ;Запрос функции 09h

int 21h ;Вызов DOS

¨ Функция 40h.Вывод данных в файл или в устройство.

Универсальная функция вывода данных из буфера пользователя в сегменте данных в файл или на устройство, дескриптор которого указывается в регистре BX. Дескриптор 1, закреплённый за стандартным устройством вывода, обеспечивает перенаправление вывода. Значение регистра CX определяет число байтов, которые должны быть выведены, а пара регистров DS:DX указывает адрес выводимых данных. Управляющие коды 08h, 0Ah, 0Dh и некоторые другие приводят к выполнению соответствующих им действий. После завершения вывода при CF = 0 регистр AX содержит число действительно выведенных байтов, а при CF =1 – возвратный код ошибки. Как и при использовании функции 3Fh, это коды ошибок 5 или 6. Пример использования.

Out_Area DB 20 DUP(?)

mov ah,40h ;Запрос функции 40h

mov bx,01 ;Дескриптор дисплея

mov cx,20 ;Число пересылаемых байт

lea dx,[Out_Area] ;Адрес буфера для выводимого сообщения

int 21h ;Вызов DOS

Дата добавления: 2014-11-10 ; просмотров: 826 . Нарушение авторских прав

Файловая система операционной системы MS-DOS: Методические рекомендации по выполнению лабораторной работы , страница 2

3. ЗАДАНИЕ И ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ

1. Ознакомьтесь с текстами программ, приведенными в Приложениях 1, 2, 3. Программы содержат примеры файлового ввода / вывода на языках С и С++.

Если те или иные функции вызывают сложности, то ознакомьтесь с ними в справочной системе Borland C++ и выполните самостоятельные примеры их использования.

2. С помощью справочной системы Borland C++ изучите синтаксис и особенности применения следующих функций стандартной библиотеки компилятора для системных вызовов MS-DOS:

а) intdos( ) , б) intdosx( ), в) int86( ), г) int86x( ), д) intr( ).

3. Выполните индивидуальное задание по теме лабораторной работы, представляющее собой разработку программы с использованием функций файловой системы MS-DOS. Для получения справочных сведений по конкретным функциям MS-DOS используйте электронный справочник TECH HELP.

4. Оформите отчет, проверьте по контрольным вопросам степень владения материалом и защитите лабораторную работу.

4. КОНТРОЛЬНЫЕ ВОПРОСЫ

1. Сформулируйте назначение и основные функции файловой системы.

2. Назовите основные черты файловой системы MS-DOS.

3. Составьте и выполните программу файлового ввода / вывода с применением функции fopen( ).

4. Составьте и выполните программу файлового ввода / вывода с использованием дескрипторов файлов

5. Составьте и выполните программу файлового ввода / вывода с помощью классов файлового ввода – вывода.

6. Чем отличаются текстовые и двоичные файлы?

7. Назовите и объясните атрибуты файлов MS-DOS. Имеются ли подобные атрибуты в ОС Windows?

8. Объясните принцип учета распределения дискового пространства с помощью FAT.

9. Как можно использовать файловые операции ввода / вывода для стандартных устройств компьютера?

10. Как осуществляется перенаправление ввода / вывода в MS-DOS?

11. Приведите примеры использования функций прерывания INT 21h для работы с файлами.

12. Составьте и выполните программу, которая с помощью функций MS-DOS создает на диске пользователя файл, записывает в него данные и выводит их на экран.

13. Составьте и выполните программу, которая с помощью функций MS-DOS создает каталог, файл в этом каталоге, записывает в него данные и перемещает файл в другой каталог.

14. Составьте и выполните программу, которая с помощью функций MS-DOS выводит сведения о полном и свободном объеме диска.

Рекомендуемая литература

1. Фролов А.В., Фролов Г.В. MS-DOS для программиста: В 2-х ч. – М.: ДИАЛОГ – МИФИ, 1997.

2. Финогенов К.Г. Самоучитель по системным функциям MS-DOS. –М.: Радио и связь, 2001.

Электронные справочники

1. TECH HELP 6.0. Flambeuax Software Inc.

// Файловый ввод-вывод с помощью потоков в стиле С

// Создается текстовый файл, в него заносится запись из двух строк

// Тип приложения — DOS, Standard

strcpy(string, «Иванов В.И.»);

if (( F = fopen(«C:\\temp\\Test.txt», «wt»)) == NULL)

printf( «Файл создать не удается»);

fprintf(F, «\t\t ХАРАКТЕРИСТИКА\n сотрудник %s,%i года рождения\n»,

// Программа демонстрации дескрипторного файлового

// ввода-вывода на языке C, файл — двоичный

// Тип приложения — Win32, Console

int i=1, j=25, i1, j1;

double a=25e6, a1;

if ((handle = open(«c:\\мои документы\\Myfile1.txt»,

O_WRONLY | O_CREAT | O_BINARY))==-1)

MessageBox(NULL, «Файл создать не удалось»,

write(handle, s, strlen(s)+1);

// Открытие файла для чтения

if ((handle = open(«c:\\мои документы\\Myfile.txt»,

MessageBox(NULL, «Файл открыть не удалось»,

read(handle, s1, strlen(s)+1);

MessageBox(NULL, «Для окончания программы нажмите OK «,

//Программа демонстрации файлового ввода-вывода

//с помощью потоков С++

// Тип приложения- Win32, Console

int i=1, j=25, i1, j1;

double a=25e6, a1;

// Создание файла как выходного потока

ofstream outfile(«c:\\мои документы\\Myfile.txt»);

MessageBox(NULL, «Файл создать не удалось»,

outfile >i1 >>j1 >> a1 >> s1;

// вывод на экран данных, прочитанных из файла

unsigned int handle;

union REGS regs;

int MakeDir(char *dname);

int MakeFile(char *filename, unsigned attr);

int WriteFile(unsigned int handle, char *str);

Вывод строки на экран в DOS

15.09.2020, 15:20

Вывод символов на экран в MASM под DOS
Недавно начал изучать ассамблер по Калашникову. У него приведен пример такой программы CSEG.

DOS неправильный вывод строки
Разбирая программу отслеживаю переходы по условию. Ветви которые в данный момент не интересуют.

Вывод информации на экран DOS: выводятся непонятные лишние символы
Ламерский вопрос. Писал программу, выводящую на экран английский алфавит и ещё пару символов.

Прерывания по Dos, Ввод и вывод текстовой строки, (Tasm)
Составить программу вывода на экран текста пословицы на английском языке. С клавиатуры к каждой.

TASM. Вывод строки в DOS по нажатию на горячую клавишу
Есть код вывода строки. Как вывести его по нажатию на клавишу, например «Г». main proc near .

15.09.2020, 16:24 2

Это готовые подпрограммы, предоставляемые ОС DOS. В ah указывается желаемая функция, в остальных регистрах недостающие данные и вызывается процедура. Только она оформлена в виде прерывания.

При изучении Windows подобные вещи называются WinAPI. Это такой же набор процедур, только оформлен не в виде прерываний, а в виде DLL.

Завершение программы нужно для передачи управления операционной системе.

15.09.2020, 17:17 [ТС] 3 15.09.2020, 18:33 4 15.09.2020, 19:01 5

Регистр сегмента стека один. Значит одна программа — один стек. При реализации резидентных программ, драйверов для DOS, в самом резиденте переключается стек. Но пока не заморачивайтесь.
Раз вы работаете по книге — перечитывайте пройденные главы. При описании программной модели процессора всё это есть.

Не задумывался над этим. Попробуйте. Думаю, что компилятор объединит все объявления в одну область — сегмент.

Добавлено через 22 минуты
Вадим77, видимо моё восприятие мира отличается от вашего тем, что для меня ассемблер всего лишь инструмент, и я не собираюсь подвергать его «краш-тестам» («а что будет, если. «). Вы к ассемблеру относитесь как новому гаджету — не умея пользоваться базовыми возможностями ищите, как накуролесить.

Я обучаюсь по подобному сценарию (каждый год по работе изучаю 1-2 новых контроллера со своими языками программирования — немного лукавлю, IEC утвердило только 5 языков, из которых распространены всего 2):
1. Ищу некий шаблон оформления. В вашем случае DOS exe программы

2. Внутрь шаблона набираю разные тестовые программы с возрастающей сложностью. Проверяю ввод, вывод, связь с внешними устройствами (модулями расширения, операторской панелью). Пробую организовать конечный автомат, инициализацию внутренних устройств (регуляторов, таймеров, и прочего). Это подзадачи требуемой мне программы.
3. После этого обучения делаю программу для заказчика. При сложностях, выделяю в новую тестовую программу проблемный фрагмент и разбираю его работу.

По мере набора, чтения статей, форумов (сам тоже задаю вопросы) приобретаю опыт, позволяющий самостоятельно ответить на вопросы о «границах дозволенного».

Основная мысль — сосредоточьтесь на языке ассемблера, оставьте на потом элементы шаблона. Когда многое прояснится — можно будет менять шаблон, понимая производимые изменения. Без этого вы за деревьями не увидите леса.

Илон Маск рекомендует:  Подсветка javascript кода
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL