



Драйвер обычно записывается как самостоятельный модуль, но без PSP, поэтому не может запускаться самостоятельно.
1. Атрибуты:
15 бит : 1- символьный драйвер
0 – блочный драйвер
14 бит : поддержка IOCTL
13 бит : формат блоков
1 – IBM
0 – любой другой
………
3 бит : 1 – часы
0 – не часы
2 бит : 1 – null
0 – не null
1 бит : 1 – STDOUT (стандарт вывода)
0 - STDIN (стандарт ввода)
2. Процедура стратегии.
Процедура стратегии выполняются только один раз на этапе загрузки и служит для запоминания длинного указателя на буфер запроса, создаваемый для драйвера самой операционной системой.
DEV_STRAT:
mov cs: SEG_PQBF, es ;
mov cs: OFF_PQBF, es ;
ret
SEG_PQBF DW ?
OFF_PQBF DW ?
3. Буфер запроса.
Структура данных, через которые прикладная программа связывается с драйвером (прикладная программа задает вид операции ввода-вывода и место расположения данных, а драйвер возвращает ей свой статус (все идет через буфер запроса)).
Буфер состоит их стандартной части 13 байт, называемой заголовок и последующей части, называемой данные, содержащей различную информацию в зависимости от вида драйвера и исполнительной операции ввода-вывода.
Заголовок запроса.
+0 : длина буфера запроса
+1 : код внешнего устройства
+2 : код команды ввода-вывода
+3 : статус
+5 : резерв
+13d : данные
4. Обработчик прерывания.
Это только процедура, которая таблично вызывает функцию, реализующую команду ввода-вывода; она завершается командой RET и выдачей статуса.
Код обработчика прерываний
dev_intpr: push A
mov ax, SEG_PQBF ;
mov es, ax ;
mov bx, OFF_PQBF ;
mov al, es:[bx+2] ;
shl al, 1 ;
xor ah, ah ; Подготовка и загрузка
lea di, FUN_TAB ; смещения функции
add di, ax ; в таблицу функции
jmp word ptr[DI] ;
FUN_TAB LABEL WORD;
DW INITIALIZE
DW CHECK_MEDIA
. . . . . . .
DW INPUT_DATA
Тринадцать . . . . . . .
функций DW OUPUT_DATA
. . . . . . .
DW OUTPUT_STATUS
. . . . . . .
DW IOCTL_OUT
Определенная функция находится в определенной строке таблицы.
Предположим что драйвер поддерживает только две функции init и out, тогда:
CHECK_MEDIA:
. . . . . .
INPUT_DATA:
. . . . . .
IOCTL_OUT:
or es.word ptr[bx]+3, 8103h
JMP QUIT
INITIALIZE:
lea ax, E_O_P
mov es, word ptr[bx]+14, ax
mov es, word ptr[bx]+16, cs
JMP QUIT
OUTPUT_DATA
QUIT:
OR es:word ptr[bx]+3, 100h
POPA
RET
В поле статус, бит
15 – ошибка
9 – драйвер занят
8 – функция завершена
с 0 – 7 – код ошибки
Пример: 8103h означает 8 – ошибка , 1 – операция завершена, 03 – неизвестная ошибка.
После разработки драйвера нужно вставить его в config.sys
Надо учесть, что драйвер не прощает ошибок. Так как он скрыт от пользователя, поэтому нельзя пользоваться отладчиком.
1. Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2014.
2. Паттерсон Д., Хеннесси Дж. Архитектура компьютера и проектирование компьютерных систем. 4-е изд. СПб.: Питер, 2012.
3. Жмакин А.П. Архитектура ЭВМ. 2-е изд. СПб.: БХВ-Петербург, 2010.
4. Орлов С.А., Цилькер Б.Я. Организация ЭВМ и систем. 2-е изд. СПб.: Питер, 2011.
5. Гук М. Аппаратные средства IBM PC. Энциклопедия 2-е изд. СПб.: Питер, 2002.
6. Зубков С.В. Assembler. Для DOS, Windows и Unix. М.: ДМК, 1999.
7. Касперски К. Техника оптимизации программ. Эффективное использование памяти. СПб.: БХВ-Петербург, 2003.
Дополнительная
1. Компьютеры на СБИС: В 2 кн. Кн.1 / Пер. с япон.; Мотоока Т., Томита С., Танака Х. и др. М.: Мир, 1988.
2. Королев Л.Н. Микропроцессоры, микро- и мини-ЭВМ. – М.: Изд-во МГУ, 1988
3. Рудометов Е., Рудометов В. Архитектура ПК, комплектующие, мультимедиа. СПб.: Питер, 2000.
4. Рудаков П.И., Финогенов К.Г. Программируем на языке ассемблера IBM PC. Обнинск: Принтер, 1999.
5. Фрир Дж. Построение вычислительных систем на базе перспективных микропроцессоров / Пер. с англ. М.: Мир, 1990.
6. Фролов А.В., Фролов Г.В. Аппаратное обеспечение персонального компьютера. М.: Диалог-МИФИ, 1997 (Библиотека системного программиста; т.33).
7. Джордейн Р. Справочник программиста ПК типа IBM PC XT и AT / Пер. с англ. М.: Финансы и статистика, 1991.
П1. Система команд процессора iX86
П1.1. Команды передачи данных
a) MOV приемник, источник; 8086, пересылка данных.
mov d, s ; (s)d ; d – destination (приемник); s – source (источник).
Команда MOV действует аналогично операторам присваивания в языках высокого уровня. Оба операнда должны быть одного и того же размера – байт, слово или двойное слово. Нельзя выполнять пересылку данных с помощью MOV из одной переменой (ячейки памяти) в другую, из одного сегментного регистра в другой, и нельзя помещать в сегментный регистр непосредственный операнд. Для пересылок из одного сегментного регистра в другой используют две команды MOV (из сегментного регистра в обычный и уже из него в другой сегментный) или пару команд PUSH/POP (более длинный по времени способ).
b) XCHG операнд1, операнд2; 8086, обмен операндов между собой;
автоматически устанавливает режим LOCK
xchg al, ah ;
xchg bx, MEM ;
Содержимое операнда 2 копируется в операнд 1, а старое содержимое операнда 1 –
на место операнда 2.
c) LEA приемник, источник; 8086, вычисление эффективного (исполнительного) адреса.
NEAR: lea bx, MEM ; эта команда аналогична команде mov bx, offset MEM.
Вычисляет эффективный адрес источника (переменная) по отношению к началу сегмента (по умолчанию DS) и помещает его в приемник (регистр).
d) LDS приемник, источник; 8086, загрузить исполнительный адрес, используя DS.
LES приемник, источник; 8086, загрузить исполнительный адрес, используя ES.
FAR: lds bx, MEM ; аналогична трем командам:
{ mov bx, offset MEM ; mov ax, seg MEM ; mov ds, ax }
Операнд-источник для этих команд – всегда переменная в памяти. Смещение адреса этой переменной загружается в РОН – приемник, а сегментная часть адреса – в сегментный регистр, заданный в операции.
e) PUSH источник; 8086, поместить данные в стек.
POP приемник; 8086, считать данные из стека.
Для пересылок между регистрами обычно применяются в виде пары команд:
push s
pop d
PUSH помещает содержимое источника в стек. Источником может быть регистр, сегментный регистр, непосредственный операнд или переменная. Фактически эта команда копирует содержимое источника в память по адресу SS:[SP] и уменьшает SP на размер источника в байтах. Начиная с 80286, команда PUSH SP помещает в стек значение SP до того, как эта же команда его уменьшит, в то время как на 8086 SP помещался в стек уже уменьшенным на два.
POP помещает в приемник слово или двойное слово, находящееся в вершине стека, увеличивая SP на два. POP выполняет действие, полностью обратное PUSH. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS, или переменная. Если в роли приемника выступает операнд, использующий ESP для косвенной адресации, команда POP вычисляет адрес операнда уже после того, как она увеличивает ESP.
Начиная с i386, появились команды pusha и popa – загрузка и выгрузка 8 регистров общего назначения.
f) IN приемник, источник; 8086, считать данные из порта.
Копирует число из порта ввода-вывода, номер которого указан в источнике, в приемник. Приемником может быть только AL, АХ или ЕАХ. Источник – или непосредственный операнд (можно указывать номера портов не больше 255), или DX (можно указывать номера портов до 65535).
g) OUT приемник, источник; 8086, записать данные в порт.
Копирует число из источника (AL, АХ или ЕАХ) в порт ввода-вывода, номер которого указан в приемнике. Приемник может быть либо непосредственным номером порта, либо регистром DX.
На командах IN и OUT строится все общение процессора с устройствами ввода-вывода.
П1.2. Команды арифметических операций над целыми числами
a) ADD приемник, источник; 8086, сложение.
add d, s; s + d d
Команда выполняет арифметическое сложение приемника и источника и помещает сумму в приемник. Приемник может быть регистром или переменной, источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Команда ADD никак не различает числа со знаком и без знака, но, употребляя значения флагов CF (перенос при сложении чисел без знака), OF (перенос при сложении чисел со знаком) и SF (знак результата), можно использовать ее и для тех, и для других.
b) ADC приемник, источник; 8086, сложение с переносом
add d, s; s + d + CF d
Эта команда во всем аналогична ADD, кроме того, что она выполняет арифметическое сложение приемника, источника и флага CF. Пара команд ADD/ADC используется для сложения чисел повышенной точности.
c) SUB приемник, источник; 8086, вычитание.
sub d, s; d – s d
Вычитает источник из приемника и помещает разность в приемник. Приемник может быть регистром или переменной, источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Точно так же, как и команда ADD, SUB не делает различий между числами со знаком и без знака, но флаги позволяют использовать ее и для тех, и для других.
d) SBB приемник, источник; 8086, вычитание с заемом.
sbb d, s; d – s – CF d
Эта команда во всем аналогична SUB, кроме того, что она вычитает из приемника значение источника и дополнительно вычитает значение флага CF.
e) СМР приемник, источник; 8086, сравнение.
cmp d, s; d – s
Сравнивает приемник и источник и устанавливает флаги. Сравнение осуществляется путем вычитания источника (число, регистр или переменная) из приемника (регистр или переменная; приемник и источник не могут быть переменными одновременно), причем результат вычитания никуда не записывается, единственным результатом работы этой команды оказывается изменение флагов CF, OF, SF, ZF, AF и PF. Обычно команду СМР используют вместе с командами условного перехода (Jcc).
f) MUL источник; 8086, умножение чисел без знака.
mul bl; bl * al ax
Выполняет умножение содержимого источника (регистр или переменная) и регистра AL, АХ, ЕАХ (в зависимости от размера источника) и помещает результат в АХ, DX:AX, EDX:EAX соответственно. Если старшая половина результата (АН, DX, EDX) содержит только нули (результат целиком поместился в младшую половину), флаги CF и OF устанавливаются в 0, иначе – в 1. Значение остальных флагов (SF, ZF, AF и PF) не определено.
g) IMUL источник; 8086, 80386, умножение чисел со знаком.
IMUL приемник, источник;
IMUL приемник, источник1, источник2;
Эта команда имеет три формы, различающиеся числом операндов:
1. IMUL источник: источник (регистр или переменная) умножается на AL, АХ или ЕАХ (в зависимости от размера операнда), и результат располагается в AX, DX:AX или EDX:EAX соответственно.
2. IMUL приемник, источник: источник (число, регистр или переменная) умножается на приемник (регистр), и результат заносится в приемник.
3. IMUL приемник, источник 1, источник 2: источник 1 (регистр или переменная) умножается на источник 2 (число), и результат заносится в приемник (регистр).
Во всех трех вариантах считается, что результат может занимать в два раза больше места, чем размер источника. В первом случае приемник автоматически оказывается достаточно большим, но во втором и третьем случаях могут произойти переполнение и потеря старших бит результата. Флаги OF и CF будут равны единице, если это произошло, и нулю, если результат умножения поместился целиком в приемник (во втором и третьем случаях) или в младшую половину приемника (в первом случае).
Значения флагов SF, ZF, AF и PF после команды IMUL не определены.
h) DIV источник; 8086, целочисленное деление без знака.
div bl; ax / bl al, ah частное в al, остаток в ah
Выполняет целочисленное деление без знака АХ или ЕАХ (в зависимости от размера источника) на источник (регистр или переменная) и помещает результат в AL, АХ или ЕАХ, а остаток – в АН, DX или EDX соответственно. Результат всегда округляется в сторону нуля, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов CF, OF, SF, ZF, AF и PF после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 – в реальном.
i) IDIV источник; 8086, целочисленное деление со знаком.
Выполняет целочисленное деление со знаком AL, АХ или ЕАХ (в зависимости от размера источника) на источник и помещает результат в AL, АХ или ЕАХ, а остаток – в АН, DX или EDX соответственно. Результат всегда округляется в сторону нуля, знак остатка всегда совпадает со знаком делимого, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов CF, OF, SF, ZF, AF и PF после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 – в реальном.
k) INC приемник; 8086, инкремент.
inc d; (d) + 1 d
Увеличивает приемник на 1. Единственное отличие этой команды от ADD состоит в том, что флаг CF не затрагивается. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом сложения.
l) DEC приемник; 8086, декремент.
dec d; (d) – 1 d
Уменьшает приемник на 1. Единственное отличие этой команды от SUB состоит в том, что флаг CF не затрагивается. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом вычитания.
m) NEG приемник; 8086, изменение знака.
neg s; -(s) s
Выполняет над числом, содержащимся в приемнике, операцию дополнения до двух. Эта операция эквивалентна обращению знака операнда, если рассматривать его как число со знаком. Если приемник равен нулю, флаг CF устанавливается в 0, иначе – в 1. Остальные флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом операции.
П1.3. Логические команды
a) AND приемник, источник; 8086, логическое И.
and d, s; s & d d
Команда выполняет побитовое «логическое И» над приемником и источником (источник и приемник не могут быть переменными одновременно) и помещает результат в приемник. Любой бит результата равен 1, только если соответствующие биты обоих операндов были равны 1, и равен 0 в остальных случаях.
b) OR приемник, источник; 8086, логическое ИЛИ.
or d, s; s ! d d
Выполняет побитовое «логическое ИЛИ» над приемником и источником (источник и приемник не могут быть переменными одновременно) и помещает результат в приемник. Любой бит результата равен 0, только если соответствующие биты обоих операндов были равны 0, и равен 1 в остальных случаях.