Лекция №1 Введение




НазваниеЛекция №1 Введение
страница5/6
Дата публикации03.03.2013
Размер1.23 Mb.
ТипЛекция
litcey.ru > Информатика > Лекция
1   2   3   4   5   6

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.
^ 2. Прямой дальний вызов.

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.

^ 3. Косвенный ближний вызов.

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 индекс в этой

; таблице.

^ 4. Косвенный дальний вызов.

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 - обработчик прерываний по /C;

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.

Взаимодействие системных и прикладных обработчиков прерываний.

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

  • прерывания, инициирующие обработчик, могут быть аппаратными (от периферийных устройств) или программными (команда INT);

  • программа обработчика может быть резидентной или транзитной;

  • вектор обрабатываемого прерывания может быть транзитным или использоваться системой;

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

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

Для того, чтобы прикладной обработчик получал управление в результате прерывания, его адрес следует поместить в соответствующий вектор прерывания. Хотя содержимое вектора прерываний можно изменить простой командой 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

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

Во многих вычислительных системах сочетание клавиш /C зарезервировано для принудительного завершения активной программы и передачи управления системе. Однако для этого нужно, чтобы DOS, обрабатывая прерывания от кла­виатуры, постоянно анализировала бы поступающие коды и "вылавливала" код нажатия /C (код ASCII 03h). MS-DOS проверяет наличие /C во входном потоке не в программе обработки прерываний от клавиатуры, а на более высоком уровне, при выполнении программных запросов. При этом различные функции DOS по-разному реагируют на ввод с клавиатуры /C.

Все функции DOS делятся на две группы - функции ввода-вывода с номерами 01h... 0Ch и все остальные функции, т.е. функции с номерами 00h, 0Dh...6Ch. Функции с номерами, превышающими 6Ch, используют расширители DOS, сетевые программы, инструментальные пакеты и другие "околосистем­ные" программы. Различие двух указанные групп заключается в том, что при вызове функций ввода-вывода DOS переходит на внутренний стек ввода-вывода, а при вызове всех остальных функций - на другой внутренний стек, который называется дисковым. Наличие в DOS двух внутренних стеков обеспечивает ее частичную реентерабельность, т.е. возможность при обнаружении ошибки в процессе выполнения какой-либо функции DOS (принадлежащей к "дисковой" группе) вызвать функции ввода-вывода для вывода на экран аварийного сообщения и ввода с клавиатуры указаний пользователя. Вопросы нереентерабельности DOS и методы ее преодоления будут рассмотрены в следующей главе.

Большая часть функций ввода вывода из диапазона 01h...0Ch проверяет перед своим выполнением наличие в коль­цевом буфере клавиатуры кода 03 (/C) и при обнару­жении этого кода выполняют команду int 23h. В этом векторе обычно находится адрес программы DOS, завершающей теку­щий процесс. Исключение составляют функции 06h и 07h, не чувствительные к /C, а также функции 02h и 09h, ко­торые (во всяком случае, в MS-DOS версий 5.0, 6.0 и 6.2) анализируют кольцевой буфер на предмет наличия там /C один раз на каждые 64 вызова. Проверка на /C осуществляется независимо от перенаправления вво­да-вывода, а также независимо от состояния системного флага BREAK.

"Дисковые" функции выполняют проверку на /C лишь в том случае, если установлен флаг BREAK, т.е. была выполнена команда DOS

BREAK ON

Таким образом, изменяя состояние BREAK, можно включать или выключать механизм реакции на /C большинства функций DOS. Заметим, что речь идет практически обо всех функциях DOS: файловых, получения или установки даты и времени, выделения и освобождения памяти, запуска и завер­шения задач и др.

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

Однако и такая возможность часто оказывается чрезмерной. При завершении задачи по /C могут остаться не восстановленными модифицированные векторы прерываний или непра­вильно закрыться открытые файлы. Поэтому большинство при­кладных программ не использует системный обработчик /C, заменяя его собственным. При выполнении такой операции необходимо иметь в виду, что вектор 23h, как, впро­чем, и любой другой, принадлежит не конкретной задаче, а всей вычислительной системе. После завершения задачи необхо­димо восстановить исходное содержимое вектора, так как в противном случае ввод /C при выполнении последую­щих задач неминуемо приведет к нарушению работы системы. Однако DOS при загрузке задачи в память копирует в опреде­ленные ячейки префикса программного сегмента содержимое векторов 22h (завершение задачи), 23h (обработка /0 и 24h (обработка критической ошибки). Стандартная системная процедура завершения задачи включает в себя восстановление исходного содержимого указанных трех векторов, которое бе­рется из префикса программного сегмента. Таким образом, даже если прикладная программа, модифицировав вектор 23h, не восстановила его, это сделает DOS в процессе завершения задачи.

В момент передачи управления через вектор 23h система находится в обычном стабильном состоянии, что позволяет ис­пользовать в обработчике любые функции DOS (например, функции вывода). При завершении обработчика командой IRET управление вернется в программу в той же точке, где она бы­ла прервана. Однако в программе обработчика можно преду­смотреть переход в любое место программы без выполнения команды IRET, что позволяет организовывать переключения по ,/C хода выполнения программы и, в частности, ее кор­ректное завершение. Следует только иметь в виду, что нажа­тие /C будет отрабатываться не немедленно, а лишь когда программа дойдет до выполнения какой-либо функции DOS. В программах с большим объемом вычислительной работы эта задержка может быть значительной.

На машинах типа IBM PC имеется вторая возможность вме­шательства в ход выполнения программы - нажатие клавиш /.

Системный обработчик прерывании от клавиатуры, входящий в состав BIOS, при обнаружении комбинации клавиш / передает управление программе, адрес кото­рой содержится в векторе 1Bh. Эта программа, также входящая в состав BIOS, состоит из единственной команды IRET и не выполняет, таким образом, никаких функций. Однако в про­цессе начальной загрузки операционной системы DOS изменяет содержимое вектора 1Bh, записывая в него адрес своего обра­ботчика. Этот обработчик, получив управление, выполняет сле­дующие действия:

  • включает 0000h в кольцевой буфер клавиатуры на место головного символа;

- модифицирует указатели кольцевого буфера так, что буфер представляется системе очищенным;

- записывает флаг / в ячейку области данных BIOS по адресу 40h:71h;

- записывает код /C (03h) в буфер драйвера консоли CON, так что драйвер "думает", что была нажата комбинация /C.

В результате, если после нажатия / про­грамма вызовет какую-либо функцию DOS, выполняющую про­верку на /C, то DOS обнаружит наличие / и передаст управление на вектор 23h точно также, как и при обнаружении /C. -Таким образом, системная обработка / и /C в итоге выполняется почти одинаково. Особенность обработки /C заключается в том, что если перед вводом /C были нажаты какие-то клавиши и их коды остались в кольцевом буфере клавиатуры, они будут "маскировать" код /C, так как драйвер консоли всегда анализирует только самый старый из символов, находящихся, в кольцевом буфере. С вводом / ситуация иная. Программа DOS, обрабатывающая прерывание 1Bh, отправляет код 03h не в кольцевой буфер клавиатуры, а непосредственно в драйвер CON. Поэтому комбинацию / нельзя замаски­ровать вводом символов с клавиатуры (к тому же, программа обработки / очищает кольцевой буфер).

Прикладная программа может заменить содержимое вектора 1Bh адресом собственного обработчика. В этом случае при на­жатии / произойдет немедленный (через про­грамму 1NT 09h и вектор 1Bh) переход на программу обработ­чика, который, таким образом, может взять на себя управле­ние практически в любой точке программы, в том числе и при зацикливании или других чисто процессорных операциях. Одна­ко такой обработчик работает на уровне прерываний, что огра­ничивает его возможности. В момент прерывания могли испол­няться какие-то программы DOS, поэтому завершение обработ­чика иначе, чем командой IRET, может привести к аварии системы. Кроме того, из обработчика нельзя обращаться к функциям DOS. Однако при всех этих ограничениях возмож­ность в любой момент вмешаться в ход выполнения программы оказывается для некоторых приложений весьма полезной.

Исходное содержимое вектора 1Bh (в отличие от вектора 23h) нс восстанавливается системой автоматически при завер­шении программы. Поэтому в прикладной программе, перехва­тывающей прерывание по /, необходимо преду­смотреть перед ее завершением восстановление исходного содер­жимого этого вектора. Однако пользователь может завершить программу и аварийно, нажав /C и обойдя, тем самым, строки нормального завершения. Поэтому в программе, пере­хватывающей вектор 1Bh, следует предусмотреть собственный обработчик прерывания по /C, в котором перед завершением программы восстанавливается

Лекция № 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. Формат записи каталога.

Смещение

Число байтов

Содержимое

00h

8

Имя файла в кодах ASCII

08h

3

Расширение имени файла в кодах ASCII

0Bh

1

Байт атрибутов файла

0Ch

10

Зарезервировано

16h

2

Время создания или последней модификации файла

18h

2

Дата создания или последней модификации файла

1Ah

2

Номер кластера, с которого начинается файл на диске

1Ch

4

Фактическая длина файла в байтах
1   2   3   4   5   6

Похожие:

Лекция №1 Введение iconАнализ к ф. м н., доцент Рудой Евгений Михайлович 2013-2014 уч год
Лекция (2 часа) Введение. Нормированные пространства. Компактные множества. Теорема Хана-Банаха
Лекция №1 Введение iconЛекция введение
Материалы данного файла могут быть использованы без ограничений для написания собственных работ с целью последующей сдачи в учебных...
Лекция №1 Введение iconЛекция «Сущность и проблемы вэд, состояние вэд в России» 1 час. 2...
Лекция «Внешнеэкономические операции и сделки: виды, классификация, организация» 1 час
Лекция №1 Введение iconЛекция 1 введение
Петрофизика сформировалась к началу 60-х годов, когда появились обобщаю­щие труды по всем вопросам изучения физических свойств пород...
Лекция №1 Введение icon1. Лекция: Введение. История, предмет, структура информатики
Хотя информатика и считается достаточно молодой наукой по отношению ко многим другим отраслям знания, но предпосылки к ее зарождению...
Лекция №1 Введение iconЛекция №1. Введение в Экономикс. Основная проблема экономики и производственные...
Под материальными потребностями подразумевается желания потребителей приобрести и использовать товары и услуги, которые доставят...
Лекция №1 Введение iconЛекция №1
Лекция № Общие принципы эффективной организации учебного процесса. Физиологиче­ская цена учебных нагрузок
Лекция №1 Введение iconЛекция №1
Лекция № Общие принципы эффективной организации учебного процесса. Физиологиче­ская цена учебных нагрузок
Лекция №1 Введение iconЛекция №1
Лекция № Общие принципы эффективной организации учебного процесса. Физиологиче­ская цена учебных нагрузок
Лекция №1 Введение iconЛекция №1
Лекция № Общие принципы эффективной организации учебного процесса. Физиологиче­ская цена учебных нагрузок
Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
litcey.ru
Главная страница