Скачать 1.23 Mb.
|
1. Прямой ближний вызов. seg segment 'code' mymain proc ;Основная программа . . . call sub ;Код Е8 dddd . . . mymain endp sub proc near ; Подпрограмма . . . ret ; Код СЗ sub endp seg ends Процедура-программа находится в том же сегменте команд, что и вызывающая программа. В коде команды dddd обозначает смещение в сегменте команд к точке входа в подпрограмму (не обязательно оформляемую в виде процедуры). При выполнении команды CALL процессор помещает адрес возврата (содержимое регистра IP) в стек выполняемой программы, после чего к текущему содержимому IP прибавляет dddd. В результате в IP оказывается адрес подпрограммы. Команда RET выполняет обратную процедуру - заносит адрес возврата в IP. ^ segl segment 'code' mymain proc ; Основная программа call far ptr sub ; Код 9А dddd ssss . . . mymain endp segl ends seg2 segment 'code' sub proc far ; Подпрограмма . . . ret ; Код CB sub2 endp seg2 ends Процедура-подпрограмма находится в другом сегменте команд той же программы. В коде команды dddd обозначает относительный адрес точки входа в подпрограмму в ее сегменте команд, а ssss - ее сегментный адрес. При выполнении команды CALL процессор помещает в стек сначала сегментный адрес вызывающей программы, а затем адрес возврата (содержимое IP). В сегментный регистр CS заносится ssss, а в IP - dddd. Поскольку процедура-подпрограмма атрибутом FAR объявлена дальней, команда RET имеет код, отличный от кода аналогичной команды ближней процедуры и выполняется по-другому: из стека извлекаются два верхних слова и переносятся в IP и CS, чем и осуществляется возврат в вызывающую программу, находящуюся в другом сегменте команд. Вместо того, чтобы объявлять процедуру дальней, можно вместо команды RET указать в явной форме команду дальнего возврата из подпрограммы RETF. ^ seg segment 'code' mymain proc ; Основная программа . . . call word ptr subadr ; Код FF 16 dddd mymain endp sub proc near ;Подпрограмма . . . ret ; Код СЗ sub endp seg ends dat segment . . . subadr dw sub ; Ячейка с адресом подпрограммы . . . dat ends Процедура-программа с атрибутом NEAR находится в том же сегменте, что и вызывающая программа, а ее относительный адрес в ячейке subadr в сегменте данных. В коде команды dddd обозначает относительный адрес слова subadr в сегменте данных. Второй байт кода команды (16 в данном примере) зависит от способа адресации. Косвенный вызов позволяет использовать разнообразные способы адресации подпрограммы: call word ptr [ВХ] ; В ВХ адрес подпрограммы call word ptr [ВХ] [SI] ; В ВХ адрес таблицы адресов ; подпрограмм, в SI индекс ; в этой таблице. call word ptr table [SI] ; table - адрес таблицы адресов ; подпрограмм, в SI индекс в этой ; таблице. ^ segl segment 'code' mymain proc ; 0сновная программа call dword ptr subadr ; Код FF IE dddd . . . mymain endp segl ends seg2 segment 'code' sub proc far ; Подпрограмма . . . ret ; Код СВ sub endp seg2 ends dat segment . . . subadr dd sub ; Двухсловная ячейка с адресом ; подпрограммы dat ends Процедура-подпрограмма с атрибутом FAR находится в другом сегменте команд той же программы, а ее полный двухсловный адрес (сегментный адрес и смещение) - в ячейке subadr в сегменте данных. Второй байт кода команды (1Е в данном примере) зависит от способа адресации. Косвенный дальний вызов, как и косвенный ближний, позволяет использовать разнообразные способы описания адреса подпрограммы Лекция № 11 Обращение к системным средствам из прикладной программы Обращение к функциям DOS и BIOS осуществляется с помощью программных прерываний (команда 1NT). Система прерываний машин типа IBM PC в принципе не ,, отличается от любой другой системы векторизованных прерываний. Самое начало оперативной памяти от адреса OOOOh до 03FFh отводится под векторы прерываний - четырехбайтовые области, в которых хранятся адреса программ обработки прерываний (ПОП). В два старшие байта каждого вектора записывается сегментный адрес ПОП, в два младшие - относительный адрес точки входа в ПОП в сегменте. Векторы, как и соответствующие им прерывания, имеют номера, называемые типами, причем вектор с номером 0 (вектор типа 0) располагается начиная с адреса 0, вектор типа 1-е адреса 4, вектор типа 2 -с адреса 8 и т.д. Вектор с номером N занимает, таким образом, байты памяти от N*4 до N*4+3, Всего в выделенной под векторы области памяти помещается 256 векторов. Получив сигнал на выполнение процедуры прерывания с определенным номером, процессор сохраняет в стеке выполняемой программы слово флагов, а также сегментный и относительный адрес сегмента команд (содержимое CS и IP) и загружает CS и IP из соответствующего вектора прерываний, осуществляя тем самым переход на ПОП (рис 3.1). ![]() Рис. 3.1. Процедура прерывания. Программа обработки прерывания обычно заканчивается командой возврата из прерывания IRET, выполняющей обратные действия - загрузку IP, CS и регистра флагов из стека, что приводит к возврату в основную программу в точку, где она была прервана. Запросы на выполнение процедуры прерываний могут иметь различную природу. Прежде всего различают аппаратные прерывания от периферийных устройств или других компонентов системы и программные прерывания, вызываемые командой INT, которая используется, в частности, для программного обращения к функциям DOS и BIOS. Сигналы, возбуждающие аппаратные прерывания, могут инициироваться цепями самого процессора, например, при попытке выполнения операции деления на ноль (такие прерывания называются внутренними, или отказами), а могут приходить из периферийного оборудования (внешние прерывания). Независимо от источника, процедура Прерывания, описанная выше, всегда выполняется одинаково, как для аппаратных, так и для программных прерываний. Большая часть векторов прерываний зарезервирована для выполнения определенных действий; часть из них автоматически заполняется адресами системных программ при загрузке системы. Векторы со следующими номерами могут представлять особый интерес для пользователя: OOh - деление на 0; Olh - пошаговое выполнение (при TF-1); 02h - немаскируемое прерывание (вывод NMI процессора) 03h - команда INT без числового параметра; 04h - INTO - прерывание по переполнению (инициируется аппаратно, но лишь при наличии в программе команды INTO); 05h - прерывание возбуждается при нажатии клавиши PrintScreen 08h - таймер (аппаратное); 09h - клавиатура (аппаратное); OAh - зарезервировано для подключения нестандартного устройства (аппаратное); OBh - второй последовательный порт COM2 (аппаратное); ОСh - первый последовательный порт СОМ1 (аппаратное); ODh - жесткий диск (PC, XT), второй параллельный порт LPT2 (AT) (аппаратное); OEh - гибкий диск (аппаратное); OFh - параллельный порт (принтер LPT1) (аппаратное); 10h - видеодрайвер BIOS; 13h - драйвер BIOS диска; 14h - драйвер последовательного порта; 16h - драйвер BIOS клавиатуры; 17h - драйвер BIOS принтера; 19h - начальный загрузчик BIOS; lAh - календарь-часы BIOS; IBh - обработчик прерываний по ICh - программа-заглушка BIOS для обработки прерываний от системного таймера (18,2 прерываний в секунду); IDh - адрес таблицы видеопараметров, BIOS; lEh - адрес -таблицы параметров дискеты, BIOS; IFh - адрес второй половины таблицы шрифтов графических режимов 4...6, BIOS; 21h - диспетчер функция DOS; 22h - адрес перехода, при завершении процесса, DOS; 23h - обработчик прерываний по 24h - обработчик прерываний по критической ошибке; 25h - абсолютное чтение диска; 26h - абсолютная запись на диск; 28h - программа-заглушка DOS для активизации резидентных программ командами с клавиатуры; 2Fh - мультиплексное прерывание DOS; 33h - драйвер мыши фирмы Microsoft; 43h - адрес таблицы шрифтов графических режимов, BIOS; 60h...66h - прерывания пользователя; 67h - драйвер дополнительной памяти LIM EMS; 68h...6Fh - свободные векторы; 70h - КМОП-часы реального времени (AT, аппаратное); 71h - программа BIOS, возбуждающая прерывание INT OAh для совместимости машин XT и AT в части обслуживания нестандартных внешних устройств (AT, аппаратное); 72h...73h - зарезервировано (AT, аппаратное); 74h - мышь (PS/2, аппаратное); 76h - жесткий диск (AT, аппаратное); 77h - зарезервировано (AT, аппаратное); 78h...7Fh - свободные векторы; Flh.-.FFh - не используются. Как видно из таблицы, векторы прерываний можно условно разбить на следующие группы: - векторы аппаратных прерываний (08h...OFh и 70h...77h); - драйверы BIOS (10h, 13h, 16h и т.д.); - программы DOS (21h, 22h, 23h и т.д.); - адреса системных таблиц BIOS (IDh, lEh, 43h и т.д.). Системные программы, адреса которых хранятся в векторах прерываний, в большинстве своем являются всего лишь диспетчерами, открывающими доступ к большим группам программ, реализующих системные функции. Так, видео драйвер BIOS (вектор 10h) включает программы смены видеорежима, управления курсором, задания цветовой палитры, загрузки шрифтов и многие другие. Особенно характерен в этом отношении вектор 21h, через который осуществляется вызов практически всех функций DOS: ввода с клавиатуры и вывода на экран, обслуживания файлов, каталогов и дисков, управления памятью и процессами, службы времени и т.д. Обращение из прикладной программы к системным функциям осуществляется единообразно. В регистр АН засылается номер функции (не путать с типом прерывания!), в другие регистры - исходные данные, необходимые для выполнения конкретной системной программы. После этого выполняется команда INT с числовым аргументом, указывающим тип (номер) прерывания, например, INT 21h. Большинство функций DOS и многие функции BIOS возвращают в флаге переноса CF код завершения. Если функция выполнилась успешно, CF=0, в случае же любой ошибки CF=1. В последнем случае в одном из регистров (чаще всего в АХ) возвращается еще и код ошибки. Таким образом, типичная процедура обращения к системным средствам выглядит следующим образом: mov AH.func ;func - номер функции ;3аполнение тех или иных регистров (AL, ВХ, ES. ВР и др.) ;параметрами, необходимыми для выполнения данной функции . . . int 2 In ; Переход в MS-DOS jc error ; Строка выполняется сразу ; после возврата из DOS ;Продолжение программы . . . error: cmp AX, 1 ; Анализ кода завершения je err1 сmр АХ2 je егг2 . . . Аналогично вызываются и функции BIOS. Взаимодействие системных и прикладных обработчиков прерываний. Программы обработки прерываний (обработчики прерываний) являются важнейшей составной частью большинства программных продуктов. Структура обработчика прерываний и его взаимодействие с остальными компонентами программного комплекса определяются рядом факторов:
Для того, чтобы прикладной обработчик получал управление в результате прерывания, его адрес следует поместить в соответствующий вектор прерывания. Хотя содержимое вектора прерываний можно изменить простой командой mov, однако предпочтительнее использовать специально предусмотренную функцию DOS 25h прерывания DOS INT 21h. В регистр AL помещается номер модифицируемого вектора, а в регистры DS:DL – адрес нового обработчика. Старое содержимое вектора следует сохранить в выделенных для этого ячейках и восстановить перед завершением программы (с помощью той же функции 25h). Для получения исходного содержимого вектора предусмотрена функция DOS 35h. Для ее вызова следует загрузить в AH номер функции - 35h, а в AL – тип вектора; двухсловное содержимое вектора возвращается в регистрах ES:BX. Структура программы с обработкой прерываний, не используемых системой, может выглядеть следующим образом: text segment ‘code’ intr proc . . . iret intr endp main proc push CS ; Установим адресуемость pop DS ; к программному сегменту mov DX,offset intr ; DS:DX-> intr mov AX,25h ; функция заполнения вектора mov AL,0Ah : тип вектора int 21h ; Вектор прерывания инициализирован ; далее текст основной программы . . . main enpd Если пользователя не устраивают системные алгоритмы обработки какого=либо прерывания, он может заменить содержимое соответствующего обработчика и выполнять всю обработку прерываний собственными силами. В этом случае следует в начале основной программы сохранить (например, в двухсловной ячейке old_09) системное содержимое вектора прерывания, а в конце восстановить его: main proc ; сохранение системного вектора в начале программы mov AH,35h ; функция получения вектор mov AL,09h ; номер вектора int 21h mov word ptr old_09,BX ; относительный адрес системного ; обработчика mov word ptr old_09+2,ES ; сегмент системного обработчика . . . ; восстановление системного вектора в конце программы push DS ; сохраним наш DS lds DX,old_09 ; заполним DS:DX из old_09 mov AH,25h ; функция заполнения вектора mov AL,09h ; номер вектора int 21h pop DS ; восстановим адресуемость . . . main endp ; поля данных old_09 dd 0 Наконец, часто требуется лишь незначительно дополнить или изменить системный алгоритм. В этих случаях используется другой подход: программа пользователя “сцепляется” с системной программой обработки прерываний, выполняя свою часть обработки либо до, либо после системной. Такая методика сцепления годится и для аппаратных, и для системных прерываний и используется очень широко. При инициализации прикладного обработчика, сцепляемого с системным, следует сохранить адрес системного обработчика, чтобы обеспечить возможность перехода в него, и поместить в вектор прерывания адрес прикладного обработчика. Если прикладная обработка доолжна выполняться после системной, как-то дополняя или корректируя ее, структура прикладного обработчика выглядит следующим образом: nem_int proc pushf call CS:old_int ; в системный обработчик с возвратом . . . ; прикладная обработка iret new_int endp После того, как процессор выполнит процедуру прерывания, в стеке прерванного процесса оказываются три слова: слово флагов, двухсловный адрес возврата в прерванную программу (рис.1.). ![]() Рис. 1. Именно такая структура данных должна быть на верху стека, чтобы команда IRET, которой завершается любая программа обработки прерываний, могла вернуть управление в прерванный процесс. Первая команда обработчика PUSHF засылает в стек еще раз слово флагов, а команда дальнего вызова процедуры CALL CS:old_int (где old_int - -двойное слово) в процессе передачи управления системному обработчику помещает в стек двухсловный адрес возврата на следующую команду прикладного обработчика. В результате в стеке формируется трехсловная структура, необходимая для команды IRET. Системный обработчик, закончив обработку данного прерывания, завершается командой IRET. Эта команда забирает из стека три верхних слова и осуществляет переход по адресу CS2:IP2, т.е. на продолжение прикладного обработчика. Завершающая команда обработчика IRET снимает со стека три верхних слова и передает управление по адресу CS1:IP1. Если прикладная обработка должна выполняться до системной, структура прикладного обработчика будет иной: newint: ; прикладная обработка . . . jmp CS:old_int Завершающая команда перехода передает управление (не затрагивая стека) в системный обработчик, который далее работает обычным образом. Иногда прикладной обработчик должен выполнить некоторые действия до передачи управления в системный, а некоторые – после. Тогда используется следующая структура обработчика: new_int proc . . . ; прикладная обработка до системной pushf call CS:old_int ; в системный обработчик с возвратом . . . ; прикладная обработка после системной iret new_int endp Наконец, бывают случаи, когда прикладной обработчик, получив управление в результате прервания, выполняет анализ ситуации и, в зависимости от результатов этого анализа, либо передает управление системному обработчику, либо выполняет обработку сам, полностью исключив системный обработчик из обслуживания конкретного акта прерывания. Тогда структура прикладного обработчика является комбинацией приведенных выше схем: new_int proc . . . ; анализ ситуации: если системная, обработка ; требуется jmp sys ; если системная обработка не требуется ; прикладная обработка . . . iret sys: jmp CS:old_int new_itn endp Обработка прерываний по Во многих вычислительных системах сочетание клавиш Все функции DOS делятся на две группы - функции ввода-вывода с номерами 01h... 0Ch и все остальные функции, т.е. функции с номерами 00h, 0Dh...6Ch. Функции с номерами, превышающими 6Ch, используют расширители DOS, сетевые программы, инструментальные пакеты и другие "околосистемные" программы. Различие двух указанные групп заключается в том, что при вызове функций ввода-вывода DOS переходит на внутренний стек ввода-вывода, а при вызове всех остальных функций - на другой внутренний стек, который называется дисковым. Наличие в DOS двух внутренних стеков обеспечивает ее частичную реентерабельность, т.е. возможность при обнаружении ошибки в процессе выполнения какой-либо функции DOS (принадлежащей к "дисковой" группе) вызвать функции ввода-вывода для вывода на экран аварийного сообщения и ввода с клавиатуры указаний пользователя. Вопросы нереентерабельности DOS и методы ее преодоления будут рассмотрены в следующей главе. Большая часть функций ввода вывода из диапазона 01h...0Ch проверяет перед своим выполнением наличие в кольцевом буфере клавиатуры кода 03 ( "Дисковые" функции выполняют проверку на BREAK ON Таким образом, изменяя состояние BREAK, можно включать или выключать механизм реакции на Поскольку проверка на Однако и такая возможность часто оказывается чрезмерной. При завершении задачи по В момент передачи управления через вектор 23h система находится в обычном стабильном состоянии, что позволяет использовать в обработчике любые функции DOS (например, функции вывода). При завершении обработчика командой IRET управление вернется в программу в той же точке, где она была прервана. Однако в программе обработчика можно предусмотреть переход в любое место программы без выполнения команды IRET, что позволяет организовывать переключения по , На машинах типа IBM PC имеется вторая возможность вмешательства в ход выполнения программы - нажатие клавиш Системный обработчик прерывании от клавиатуры, входящий в состав BIOS, при обнаружении комбинации клавиш
- модифицирует указатели кольцевого буфера так, что буфер представляется системе очищенным; - записывает флаг - записывает код В результате, если после нажатия Прикладная программа может заменить содержимое вектора 1Bh адресом собственного обработчика. В этом случае при нажатии Исходное содержимое вектора 1Bh (в отличие от вектора 23h) нс восстанавливается системой автоматически при завершении программы. Поэтому в прикладной программе, перехватывающей прерывание по Лекция № 12 Резидентные программы Основы организации резидентных программ Большой класс программ, обеспечивающих функционирование вычислительной системы (драйверы устройств, оболочки DOS, программы шифрации и защиты данных, русификаторы, обслуживающие программы типа электронных блокнотов или калькуляторов и др.), должны постоянно находиться в памяти и мгновенно реагировать на запросы пользователя, или на какие-то события, происходящие в вычислительной системе. Такие программы носят названия программ, резидентных в памяти (Terminate and Stay Resident, TSR), или просто резидентных программ. Сделать резиденцией можно как программу типа .СОМ, так и программу типа .ЕХЕ, однако поскольку резидентная программа должна быть максимально компактной, чаще всего в качестве резидентной используют программы типа .СОМ. Программы, предназначенные для загрузки и оставления в памяти, обычно состоят из двух частей (секций) - инициализирующей и рабочей (резидентной). В тексте программы резидентная секция размещается в начале, инициализирующая – за ней. При первом вызове программы она загружается в память целиком и управление передается секции инициализации, которая заполняет или модифицирует векторы прерываний, настраивает программу на конкретные условия работы (возможно, исходя из параметров, переданных программе при ее вызов с помощью параметров командной строки) и с помощью прерывания DOS int 21h с функцией 31h завершает программу, оставляя в памяти се резидентную часть. Размер резидентной части программы (в параграфах) передастся DOS в регистре AН Указывать при этом сегментный адрес программы нет необходимости, так как он известен DOS. Для определения размера резидентной секции ее можно завершить предложением вида: ressize=&-myproc где myproc - смещение начала программы, а при вызове функции 31h в регистр DX заслать результат вычисления выражения (ressize+10Fh)/16. Функция 31h, закрепив за резидентной программой необходимую для ее функционирования память, передает управление командному процессору СОММАМD.СОМ, и вычислительная система переходит, таким образом, и исходное состояние. Наличие программы, резидентной в памяти, никак не отражается на ходе вычислительного процесса за исключением того, что уменьшается объем свободной памяти. Одновременно может быть загружено несколько резидентных программ. Для того, чтобы активизировать резидентную программу, ей надо как-то передать управление и, возможно, параметры. Запустить резидентную программу можно тремя способами: - вызвать ее оператором CALL как подпрограмму; - использовать механизм асинхронных (аппаратных) прерываний; - с помощью синхронного (программного) прерывайся. Кроме того, специально для взаимодействия с резидентными программами в DOS предусмотрено мультиплексное прерывание 2Fh. Первый способ требует наличия в памяти текущей активной программы, которая, очевидно, должна образовывать с родительской программой единый программный комплекс с определенными заранее соглашениями взаимодействия (межпрограммным интерфейсом). Оформив в виде резидентной программы процедуры выполнения функций, общих для группы транзитных программ, можно упростить структуру и объем транзитных программ такого многопрограммного комплекса. Второй способ, асинхронная активизация резидентной программы внешним прерыванием (от таймера, клавиатуры, последовательного порта или другого периферийного оборудования) широко используется системными и прикладными резидентными программами: спулерами принтеров, программами календарей-часов, русификаторами, калькуляторами, электронными блокнотами, резидентными электронными справочниками и базами данных и т.д. Наконец, синхронная передача управления резидентной программе с помощью команды INT является основой взаимодействия с функциями DOS и BIOS и иногда используется в прикладных резидентных программах, в частности, при их отладке с помощью прерывания INT 3. Рассмотрим типичную структуру резидентной программы и системные средства оставления ее в памяти. Как уже отмечалось, резидентные программы чаще всего пишутся в формате .COM: text segment ‘code’ assume CS:text, DS:text org 100h myproc proc far jmp init ; Переход на секцию инициалов ;Данные резидентной секции программы . . . entry: . . . ; Текст резидентной секции программы iret myproc endp ressize=equ=$-myproc ; Размер (в байтах) резидентной секции ; программы init proc ; Секция инициализации . . . mov DX,(ressize+10Fh)/16 ; Размер в параграфах mov AX,3100h ; Функция "завершить и оставить в памяти" int 21h init endp text ends end myproc При первом запуске программы с клавиатуры управление предается на начало процедуры myproc (первый байт префикса программного сегмента). Командой JMP осуществляется переход на секцию инициализации, в которой, в частности, подготавливаются условия для дальнейшей активизации программы уже в резидентном состоянии. Последними строками секции инициализации вызывается функция 31h, которая, выполняет завершение программы с оставлением в памяти указанной ее части. С целью экономии памяти секция инициализации располагается в конце программы и отбрасывается при ее завершении. • Содержательная часть резидентной программы, начинающаяся с метки entry, активизируется, как уже отмечалось выше с помощью аппаратного или программного прерывания или командой CALL. В последнем случае программа резидентной стадии заканчивается командой RET (вместо IRET). На рис. 1 приведена типичная структура резидентной программы. Как видно из рис.1, резидентная программа имеет по крайней мере две точки входа. После загрузки программы в память командой оператора, вводимой на командной строке управление передается в точку, указанную в поле завершающего текст программы оператора end (на рисунке – начало процедуры myproc). Для программ типа .СОМ эта точка должна соответствовать самой первой строке, программы, идущей вслед за префиксом программного сегмента. Поскольку при загрузке программы должна выполниться ее установка в памяти, первой командой программы всегда является команда перехода на секцию инициализации и установки (jmp init на рисунке). Р ![]() ис. 1. Структура резидентной программы. После установки в памяти резидентная программа остается пассивной и никак не проявляет своего существования, пока не будет активизирована предусмотренным в ней для этого способом (аппаратным или программным прерыванием или командой дальнего вызова). Эта, вторая точка вызова обозначена на рисунке меткой entry. Связь с резидентной программой Для обращения к резидентной программе из транзитной можно использовать область межзадачных связей, являющуюся частью области данных BIOS и расположенную по адресам 40h:F0h...40h:FFh. Эта область не используется системой и предназначена специально для коммуникации программ пользователя. С помощью области межзадачных связей можно осуществлять как вызов резидентной программы, так и передачу параметров. Удобнее передавать не сами параметры, а их адреса; поскольку полный адрес занимает два слова, в области межзадачной связи помещается 4 адреса. По ходу выполнения секции инициализации будущая резидентная программа помещает в обусловленные ячейки области межзадачной связи адрес своей точки входа, например, в слово 40h:FОh относительный адрес команды с меткой entry, а в слово 40h:F2h - содержимое сегментного регистра CS. Транзитная программа, желая передать управление резидентной, настраивает регистр ES на начало области данных BIOS и выполняет команду дальнего вызова call dword ptr ES:OFOh В этом случае резидентная программа должна быть объявлена, как дальняя процедура (myproc proc far) и завершаться командой RET дальнего возврата. Если резидентной программе требуется передавать параметры, их начальный адрес (или, при необходимости, адрес целого списка адресов) заносится транзитной программой в другую обусловленную ячейку области межзадачной связи, например, двухсловную ячейку 40h:F4h. В этом случае резидентная программа переносит, например, в регистр SI относительный адрес параметра из ячейки 40h:F4h, а в регистр DS - сегментный адрес параметра из ячейки 40h:F6h и после этого забирает сами параметры командами типа mov AX,DS:[SI] mov BX,DS:[SI+2] и т.д. Естественно, перед началом выполнения резидентная программа должна сохранить все используемые ею регистры (а перед завершением - восстановить их). Более изящный метод передачи резидентной программе управления и параметров заключается в использовании свободных векторов, например, 60h...66h. В процессе инициализации резидентная программа помещает свой адрес в свободный вектор: mov АХ.0 mov ES.AX mov ES:180h,offset entry ;Адрес вектора 60h mov ES:182h,CS Для активизации резидентной программы в транзитной программе достаточно выполнить команду Int 60h В этом случае резидентная программа должна заканчиваться командой IRET. Адреса параметров можно передавать через другие свободные векторы, например, 61h или 62h. Естественно, по-прежнему можно воспользоваться областью межзадачных связей. Если резидентная программа должна запускаться непосредственно с клавиатуры, адрес ее точки входа entry должен быть помещен в вектор прерываний от клавиатуры 09h. При этом, естественно, возникает проблема взаимодействия с системным обработчиком прерываний от клавиатуры (а также русификатором и остальным программами, перехватывающими прерывание 09h). Вопросы взаимодействия прикладных и системных обработчиков прерываний были рассмотрены в предыдущей главе. Следует заметить, что реальные резидентные программы, как правило, перехватывают целый ряд аппаратных и программных прерываний и имеют, соответственно, не одну точку входа активизации, а несколько. Необходимость такого построения резидентных программы будет обоснована ниже. Для взаимодействия с параллельными процессами и, в частности, с резидентными программами в системе MS-DOS предусмотрен стандартный интерфейс - прерывание 2Fh. Перед вызовом этого прерывания следует поместить в регистр АН номер функции, а в регистр AL - номер подфункции. Функции 00h.-.BFh зарезервированы за DOS (например, функция 0lh позволяет управлять процессом вывода файлов на печать с помощью системной программы PRINT.СОМ, а функция 02h дает возможность определить, загружена ли резидентная часть утилиты - расширения DOS ASSIGN); функции C0h...FFh зарезервированы для прикладных программ. Если с помощью прерывания 2Fh предполагается передача в резидентную программу или получение из нее большого количества параметров, можно использовать и другие регистры, например, DS:DX или DS:SI и передавать через них адреса списков параметров. Согласно системным соглашениям прерывание 2Fh возвращает в регистре AL состояние резидентной программы: AL=0 - программа не установлена (т.е. в памяти еще нет этой резидентной программы) и ее можно устанавливать; AL=1 - программа не установлена и ее установить нельзя; AL=FFh - программа уже установлена и, следовательно, ее повторная установка не требуется. В случае ошибки следует установить флаг CF, а в регистре АХ вернуть код ошибки. Прерывание 2Fh используется прежде всего с целью исключить повторную установку уже загруженной в память программы; иногда с помощью этого прерывания уже загруженной резидентной программе передается необходимая информация (например, приказ на выгрузку из памяти). Для того, чтобы резидентная прикладная программа отзывалась на прерывание 2Fh, в нее следует включить прикладной обработчик одной или нескольких функций этого прерывания. Тогда вызов соответствующей функции этого прерывания в любой транзитной (или другой резидентной) программе позволит организовать взаимодействие с загруженной резидентной программой. Рассмотрим структуру резидентной программы с обработчиком прерывания 2Fh. Закрепим за нашей программой функцию C0h этого прерывания. ;Секция инициализации ;Сохраним адрес системного обработчика 2Fh, чтобы не лишать себя ;возможности использовать системные функции этого прерывания init: mov AH,35h ;Функция получения вектора mov AL,2Fh ;Номер вектора Int 2fh mov word ptr old_ 2fh,BX ;Сохраним вектор 2Fh mov word ptr old_2fh+2,ES ;в ячейке old2fh ;Загрузим в вектор ZFh адрес нашего обработчика mov AH,25h ;Функция установки вектора mov AL,2Fh ;Номер вектора mov DX,offset new_2fh int 2lh ;Другие действия по инициализации ;Завершим программу, оставив ее резидентной в памяти с помощью ;функции 31h прерывания DOS 2lh ;Резидентные поля данных old_2fh dd 0 ;Ячейка для сохранения исходного ;содержимого вектора 2Fh ;Рабочая секция entry: . . . iret ;Наш обработчик прерывания 2Fh (функции C0h) new_2fh: cmp AH.0C0h ;Наша функция? je C0h ;Наша! jmp CS:old_2fh ;He наша, в системный обработчик c0h: ;Возможно, анализ AL и переходы на программы реализации подфункций: ;передача или получение параметров, настройка резидентной программы, ;выгрузка ее из памяти и т.д. iret ;Возврат в вызвавшую программу Лекция № 13 Работа с файлами, каталогами и дисками Основные характеристики файловой системы MS-DOS В машинах типа IBM PC предусмотрены два уровня обращения к магнитным дискам. При работе на нижнем уровне пользователь с помощью прерывания BIOS INT 13h обращается непосредственно к программам управления диска. Типичными операциями этого уровня являются запись или чтение сектора, позиционирование головок, форматирование дорожки. Файловая система DOS не используется; требуемая информация отыскивается не по имени файла, а по номерам поверхности, цилиндра и сектора. Верхний уровень реализуется с помощью прерывания DOS INT 21h, поддерживающего, наряду с прочими, также и функции обслуживания файловой структуры. Программист работает не с программами управления физическим диском, а с файловой системой DOS, получая возможность оперировать такими понятиями файловой системы, как логический диск, каталог, файл. Как известно, для удобства работы с большим количеством разнородных файлов в DOS используется древовидная структура каталогов. Каталог представляет собой файл обычно относительно небольшого размера, в котором содержится перечень всех подкаталогов следующего уровня и файлов, входящих в данный каталог. Каждому подкаталогу или файлу отводится одна запись размером 32 байт, в которую DOS заносит информацию о файле: имя, начальный адрес на диске (номер кластера), дата и время создания, длина в байтах, а также набор характеристик файла, называемых его атрибутами. Кроме записей, относящихся к нижележащим каталогам и файлам, каждый каталог содержит еще две записи: о себе самом и о родительском каталоге. Формат записи каталога (как корневого, так и любого подкаталога) приведен в табл. 4. 1. Атрибут файла (в том числе файла каталога) хранятся в специально отведенном для них байте атрибутов и могут иметь значения, приведенные в табл. 4. 2. Таблица 4. 1. Формат записи каталога.
|
![]() | Анализ к ф. м н., доцент Рудой Евгений Михайлович 2013-2014 уч год Лекция (2 часа) Введение. Нормированные пространства. Компактные множества. Теорема Хана-Банаха | ![]() | Лекция введение Материалы данного файла могут быть использованы без ограничений для написания собственных работ с целью последующей сдачи в учебных... |
![]() | Лекция «Сущность и проблемы вэд, состояние вэд в России» 1 час. 2... Лекция «Внешнеэкономические операции и сделки: виды, классификация, организация» 1 час | ![]() | Лекция 1 введение Петрофизика сформировалась к началу 60-х годов, когда появились обобщающие труды по всем вопросам изучения физических свойств пород... |
![]() | 1. Лекция: Введение. История, предмет, структура информатики Хотя информатика и считается достаточно молодой наукой по отношению ко многим другим отраслям знания, но предпосылки к ее зарождению... | ![]() | Лекция №1. Введение в Экономикс. Основная проблема экономики и производственные... Под материальными потребностями подразумевается желания потребителей приобрести и использовать товары и услуги, которые доставят... |
![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок | ![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок |
![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок | ![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок |