Перехват прерываний

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

Рубрика Программирование, компьютеры и кибернетика
Вид контрольная работа
Язык русский
Дата добавления 13.08.2011
Размер файла 81,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

; чтобы получить адрес атрибута,

; а не символа

mov al, 071h; атрибут - синий на сером

stosb; вывод на экран

ret

display_all endp

int09h_handler endp; конец обработчика INT 09h

; буфер для хранения содержимого части экрана, которая накрывается нашим окном

screen_buffer db 1190 dup(?)

; первая строка окна

display_line1 db 0DAh, 11 dup (0C4h), '* ASCII *', 11 dup (0C4h), 0BFh

; последняя строка окна

display_line2 db 0C0h, 11 dup (0C4h), '* Hex '

hex_byte1 db?; старшая цифра текущего байта

hex_byte2 db?; младшая цифра текущего байта

db ' *', 10 dup (0C4h), 0D9h

hw_reset2D: retf; ISP: минимальный hw_reset

; обработчик прерывания INT 2Dh

; поддерживает функции AMIS 3.6 00h, 02h, 03h, 04h и 05h

int2Dh_handler proc far

jmp short actual_int2Dh_handler; ISP: пропустить блок

old_int2Dh dd?; ISP: старый обработчик

dw 424Bh; ISP: сигнатура

db 00h; ISP: программное прерывание

jmp short hw_reset2D; ISP: ближний jmp на hw_reset

db 7 dup (0); ISP: зарезервировано

actual_int2Dh_handler:; начало собственно обработчика INT 2Dh

db 80h, 0FCh; начало команды CMP АН, число

mux_id db; идентификатор программы

je its_us; если вызывают с чужим АН - это не нас

jmp dword ptr cs:old_int2Dh

its_us:

cmp al, 06; функции 06h и выше

jae int2D_no; не поддерживаются

cbw; AX = номер функции

mov di, ax; DI = номер функции

shl di, 1; умножить его на 2, так как jumptable -

; таблица слов

jmp word ptr cs:jumptable[di]; косвенный переход на обработчики

; функций

jumptable dw offset int2D_00, offset int2D_no

dw offset int2D_02, offset int2D_03

dw offset int2D_04, offset int2D_05

int2D_00:; проверка наличия

mov al, 0FFh; этот номер занят

mov сх, 0100h; номер версии 1.0

push cs

pop dx; DX:DI - адрес AMIS-сигнатуры

mov di, offset amis_sign

iret

int2D_no:; неподдерживаемая функция

mov al, 00h; функция не поддерживается

iret

int2D_02:; выгрузка программы

mov byte ptr cs:disable_point, 0CFh; записать код команды IRET

; по адресу disable_point

; в обработчик INT 09h

mov al, 04h; программа дезактивирована, но сама

; выгрузиться не может

mov bx, cs; BX - сегментный адрес программы

iret

int2D_03:; запрос на активизацию для «всплывающих» программ

cmp byte ptr we_are_active, 0; если окно уже на экране,

je already_popup

call save_screen; сохранить область экрана,

push cs

pop ds

call display_all; вывести окно

mov byte ptr we_are_active, 1; и поднять флаг

already_popup:

mov al, 03h; код 03: программа активизирована

iret

int2D_04:; получить список перехваченных прерываний

mov dx, cs; список в DX:BX

mov bx, offset amis_hooklist

iret

int2D_05:; получить список «горячих» клавиш

mov al, 0FFh; функция поддерживается

mov dx, cs; список в DX:BX

mov bx, offset amis_hotkeys

iret

int2Dh_handler endp

; AMIS: сигнатура для резидентных программ

amis_sign db «Cubbi…»; 8 байт - имя автора

db «ASCII…»; 8 байт - имя программы

db «ASCII display and input utility», 0; ASCIZ-комментарий

; не более 64 байт

; AMIS: список перехваченных прерываний

amis_hooklist db 09h

dw offset int09h_handler

db 2Dh

dw offset int2Dh_handler

; AMIS: список «горячих» клавиш

amis_hotkeys db 01h; клавиши проверяются после стандартного

; обработчика INT 09h

db 1; число клавиш

db 1Eh; скан-код клавиши (А)

dw 08h; требуемые флаги (любая Alt)

dw 0; запрещенные флаги

db 1; клавиша глотается

; конец резидентной части

; начало процедуры инициализации

initialize proc near

mov ah, 9

mov dx, offset usage; вывести информацию о программе

int 21h

; проверить, не установлена ли уже наша программа

mov ah, - 1; сканирование номеров от FFh до 00h

more_mux:

mov al, 00h; Функция 00h - проверка наличия программы

int 2Dh; мультиплексорное прерывание AMIS,

cmp al, 00h; если идентификатор свободен,

jne not_free

mov byte ptr mux_id, ah; записать его номер прямо в код

; обработчика int 2Dh,

jmp short next_mux

not_free:

mov es, dx; иначе - ES:DI = адрес их сигнатуры

mov si, offset amis_sign; DS:SI = адрес нашей сигнатуры

mov cx, 16; сравнить первые 16 байт,

repe cmpsb

jcxz already_loaded; если они не совпадают,

next_mux:

dec ah; перейти к следующему идентификатору,

jnz more_mux; пока это не 0

; (на самом деле в этом примере сканирование происходит от FFh до 01h,

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

; номера в следующей строке)

free_mux_found:

cmp byte ptr mux_id, 0; если мы ничего не записали,

je no_more_mux; идентификаторы кончились

mov ax, 352Dh; АН = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 2Dh

mov word ptr old_int2Dh, bx; и поместить его в old_int2Dh

mov word ptr old_int2Dh+2, es

mov ax, 3509h; AH = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 09h

mov word ptr old_int09h, bx; и поместить его в old_int09h

mov word ptr old_int09h+2, es

mov ax, 252Dh; AH = 25h, AL = номер прерывания

mov dx, offset int2Dh_handler; DS:DX - адрес нашего

int 21h; обработчика

mov ax, 2509h; AH = 25h, AL = номер прерывания

mov dx, offset int09h_handler; DS:DX - адрес нашего

int 21h; обработчика

mov ah, 49h; AH = 49h

mov es, word ptr envseg; ES = сегментный адрес среды DOS

int 21h; освободить память

mov ah, 9

mov dx, offset installed_msg; вывод строки об успешной

int 21h; инсталляции

mov dx, offset initialize; DX - адрес первого байта за

; концом резидентной части

int 27h; завершить выполнение, оставшись

; резидентом

; сюда передается управление, если наша программа обнаружена в памяти

already_loaded:

mov ah, 9; АН = 09h

mov dx, offset already_msg; вывести сообщение об ошибке

int 21h

ret; и завершиться нормально

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

; резидентными программами

no_more_mux:

mov ah, 9

mov dx, offset no_more_mux_msg

int 21h

ret

; текст, который выдает программа при запуске:

usage db «ASCII display and input program»

db «v1.0», 0Dh, 0Ah

db «Alt-A - активация», 0Dh, 0Ah

db «Стрелки - выбор символа», 0Dh, 0Ah

db «Enter - ввод символа», 0Dh, 0Ah

db «Escape - выход», 0Dh, 0Ah

db «$»

; текст, который выдает программа, если она уже загружена:

already_msg db «Ошибка: программа уже загружена», 0Dh, 0Ah, '$'

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

no_more_mux_msg db «Ошибка: Слишком много резидентных программ»

db 0Dh, 0Ah, '$'

; текст, который выдает программа при успешной установке:

installed_msg db «Программа загружена в память», 0Dh, 0Ah, '$'

initialize endp

end start

Резидентная часть этой программы занимает в памяти целых 2064 байта (из которых на собственно коды команд приходится только 436). Это вполне терпимо, учитывая, что обычно программа типа ascii.com запускается перед простыми текстовыми редакторами для DOS (edit, multiedit, встроенные редакторы оболочек типа Norton Commander и т.д.), которые не требуют для своей работы полностью свободной памяти. В других случаях, как, например, при создании программы, копирующей изображение с экрана в файл, может оказаться, что на счету каждый байт; такие программы часто применяют для сохранения изображений из компьютерных игр, которые задействуют все ресурсы компьютера по максимуму. Здесь резидентным программам приходится размещать данные, а иногда и часть кода, в старших областях памяти, пользуясь спецификациями HMA, UMB, EMS или XMS.

Выгрузка резидентной программы из памяти

Чтобы выгрузить резидентную программу из памяти, необходимо сделать три вещи: закрыть открытые программой файлы и устройства, восстановить все перехваченные векторы прерываний, и наконец, освободить всю занятую программой память. Трудность может вызвать второй шаг, так как после нашего резидента могли быть загружены другие программы, перехватившие те же прерывания. Если в такой ситуации восстановить вектор прерывания в значение, которое он имел до загрузки нашего резидента, программы, загруженные позже, не будут получать управление. Более того, они не будут получать управление только по тем прерываниям, которые у них совпали с прерываниями, перехваченными нашей программой, в то время как другие векторы прерываний будут все еще указывать на их обработчики, что почти наверняка приведет к ошибкам. Поэтому, если хоть один вектор прерывания не указывает на наш обработчик, выгружать резидентную программу нельзя. Это всегда было главным вопросом, и спецификации AMIS и IBM ISP (см. предыдущую главу) являются возможным решением этой проблемы. Если вектор прерывания не указывает на нас, имеет смысл проверить, не указывает ли он на ISP-блок (первые два байта должны быть EBh 10h, а байты 6 и 7 - «K» и «B»), и, если это так, взять в качестве вектора значение из этого блока и т.д. Кроме того, программы могут изменять порядок, в котором обработчики одного и того же прерывания вызывают друг друга.

Последний шаг в выгрузке программы - освобождение памяти - можно выполнить вручную, вызывая функцию DOS 49h на каждый блок памяти, который программа выделяла через функцию 48h, на блок с окружением DOS, если он не освобождался при загрузке, и наконец, на саму программу. Однако есть способ заставить DOS сделать все это (а также закрыть открытые файлы и вернуть код возврата) автоматически, вызвав функцию 4Ch, объявив резидент текущим процессом. Посмотрим, как это делается на примере резидентной программы, занимающей много места в памяти. Кроме того, этот пример реализует все приемы, использующиеся для вызова функций DOS из обработчиков аппаратных прерываний, о которых рассказано в главе 5.8.3.

; scrgrb.asm

; Резидентная программа, сохраняющая изображение с экрана в файл.

; Поддерживается только видеорежим 13h (320x200x256) и только один файл.

; HCI:

; Нажатие Alt-G создает файл scrgrb.bmp в текущем каталоге с изображением,

; находившимся на экране в момент нажатия клавиши.

; Запуск с командной строкой /u выгружает программу из памяти

; API:

; Программа занимает первую свободную функцию прерывания 2Dh (кроме нуля)

; в соответствии со спецификацией AMIS 3.6

; Поддерживаемые подфункции AMIS: 00h, 02h, 03h, 04h, 05h

; Все обработчики прерываний построены в соответствии с IBM ISP

; Резидентная часть занимает в памяти 1056 байт, если присутствует EMS,

; и 66 160 байт, если EMS не обнаружен

model tiny

code

186; для сдвигов и команд pusha/popa

org 2Ch

envseg dw?; сегментный адрес окружения

org 80h

cmd_len db?; длина командной строки

cmd_line db?; командная строка

org 100h; COM-программа

start:

jmp initialize; переход на инициализирующую часть

; Обработчик прерывания 09h (IRQ1)

int09h_handler proc far

jmp short actual_int09h_handler; пропустить ISP

old_int09h dd?

dw 424Bh

db 00h

jmp short hw_reset

db 7 dup (0)

actual_int09h_handler:; начало собственно обработчика INT 09h

pushf

call dword ptr cs:old_int09h; сначала вызвать старый

; обработчик, чтобы он завершил аппаратное

; прерывание и передал код в буфер

pusha; это аппаратное прерывание - надо

push ds; сохранить все регистры

push es

push 0040h

pop ds; DS = сегментный адрес области данных BIOS

mov di, word ptr ds:001Ah; адрес головы буфера

; клавиатуры,

cmp di, word ptr ds:001Ch; если он равен адресу

; хвоста,

je exit_09h_handler; буфер пуст, и нам делать нечего,

mov ax, word ptr [di]; иначе: считать символ,

cmp ah, 22h; если это не G (скан-код 22h),

jne exit_09h_handler; выйти

mov al, byte ptr ds:0017h; байт состояния клавиатуры,

test al, 08h; если Alt не нажата,

jz exit_09h_handler; выйти,

mov word ptr ds:001Ch, di; иначе: установить адреса головы

; и хвоста буфера равными, то есть

; опустошить его

call do_grab; подготовить BMP-файл с изображением

mov byte ptr cs:io_needed, 1; установить флаг

; требующейся записи на диск

cli

call safe_check; проверить, можно ли вызвать DOS,

jc exit_09h_handler

sti

call do_io; если да - записать файл на диск

exit_09h_handler:

pop es

pop ds; восстановить регистры

рора

iret; и вернуться в прерванную программу

int09h_handler endp

hw_reset: retf

; Обработчик INT 08h (IRQ0)

int08h_handler proc far

jmp short actual_int08h_handler; пропустить ISP

old_int08h dd?

dw 424Bh

db 00h

jmp short hw_reset

db 7 dup (0)

actual_int08h_handler:; собственно обработчик

pushf

call dword ptr cs:old_int08h; сначала вызвать стандартный

; обработчик, чтобы он завершил

; аппаратное прерывание (пока оно

; не завершено, запись на диске невозможна)

pusha

push ds

cli; между любой проверкой глобальной переменной

; и принятием решения по ее значению -

; не повторно входимая область, прерывания

; должны быть запрещены

cmp byte ptr cs:io_needed, 0; проверить,

je no_io_needed; нужно ли писать на диск

call safe_check; проверить,

jc no_io_needed; можно ли писать на диск

sti; разрешить прерывания на время записи

call do_io; запись на диск

no_io_needed:

pop ds

рора

iret

int08h_handler endp

; Обработчик INT 13h

; поддерживает флаг занятости INT 13h, который тоже надо проверять перед

; записью на диск

int13h_handler proc far

jmp short actual_int13h_handler; пропустить ISP

old_int13h dd?

dw 424Bh

db 00h

jmp short hw_reset

db 7 dup (0)

actual_int13h_handler:; собственно обработчик

pushf

inc byte ptr cs:bios_busy; увеличить счетчик занятости INT 13h

cli

call dword ptr cs:old_int13h

pushf

dec byte ptr cs:bios_busy; уменьшить счетчик

popf

ret 2; имитация команды IRET, не восстанавливающая

; флаги из стека, так как обработчик INT 13h возвращает некоторые

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

; в стеке. Он тоже завершается командой ret 2

int13h_handler endp

; Обработчик INT 28h

; вызывается DOS, когда она ожидает ввода с клавиатуры и функциями DOS можно

; пользоваться

int28h_handler proc far

jmp short actual_int28h_handler; пропустить ISP

old_int28h dd?

dw 424Вh

db 00h

jmp short hw_reset

db 7 dup (0)

actual_int28h_handler:

pushf

push di

push ds

push cs

pop ds

cli

cmp byte ptr io_needed, 0; проверить,

je no_io_needed2; нужно ли писать на диск

lds di, dword ptr in_dos_addr

cmp byte ptr [di+1], 1; проверить,

ja no_io_needed2; можно ли писать на диск (флаг

; занятости DOS не должен быть больше 1)

sti

call do_io; запись на диск

no_io_needed2:

pop ds

pop di

popf

jmp dword ptr cs:old_int28h; переход на старый

; обработчик INT 28h

int28h_handler endp

; Процедура do_grab

; помещает в буфер палитру и содержимое видеопамяти, формируя BMP-файл.

; Считает, что текущий видеорежим - 13h

do_grab proc near

push cs

pop ds

call ems_init; отобразить наш буфер в окно EMS

mov dx, word ptr cs:buffer_seg

mov es, dx; поместить сегмент с буфером в ES и DS

mov ds, dx; для следующих шагов процедуры

mov ax, 1017h; Функция 1017h - чтение палитры VGA

mov bx, 0; начиная с регистра палитры 0,

mov сх, 256; все 256 регистров

mov dx, BMP_header_length; начало палитры в BMP

int 10h; видеосервис BIOS

; перевести палитру из формата, в котором ее показывает функция 1017h

; (три байта на цвет, в каждом байте 6 значимых бит),

; в формат, используемый в BMP-файлах

; (4 байта на цвет, в каждом байте 8 значимых бит)

std; движение от конца к началу

mov si, BMP_header_length+256*3-1; SI - конец 3-байтной палитры

mov di, BMP_header_length+256*4-1; DI - конец 4-байтной палитры

mov сх, 256; СХ - число цветов

adj_pal:

mov al, 0

stosb; записать четвертый байт (0)

lodsb; прочитать третий байт

shl al, 2; масштабировать до 8 бит

push ax

lodsb; прочитать второй байт

shl al, 2; масштабировать до 8 бит

push ax

lodsb; прочитать третий байт

shl al, 2; масштабировать до 8 бит

stosb; и записать эти три байта

pop ax; в обратном порядке

stosb

pop ax

stosb

loop adj_pal

; Копирование видеопамяти в BMP.

; В формате BMP строки изображения записываются от последней к первой, так что

; первый байт соответствует нижнему левому пикселю

cld; движение от начала к концу (по строке)

push 0A000h

pop ds

mov si, 320*200; DS:SI - начало последней строки на экране

mov di, bfoffbits; ES:DI - начало данных в BMP

mov dx, 200; счетчик строк

bmp_write_loop:

mov cx, 320/2; счетчик символов в строке

rep movsw; копировать целыми словами, так быстрее

sub si, 320*2; перевести SI на начало предыдущей строки

dec dx; уменьшить счетчик строк,

jnz bmp_write_loop; если 0 - выйти из цикла

call ems_reset; восстановить состояние EMS

; до вызова do_grab

ret

do_grab endp

; Процедура do_io

; создает файл и записывает в него содержимое буфера

do_io proc near

push cs

pop ds

mov byte ptr io_needed, 0; сбросить флаг требующейся

; записи на диск

call ems_init; отобразить в окно EMS наш буфер

mov ah, 6Ch; Функция DOS 6Ch

mov bx, 2; доступ - на чтение / запись

mov cx, 0; атрибуты - обычный файл

mov dx, 12h; заменять файл, если он существует,

; создавать, если нет

mov si, offset filespec; DS:SI - имя файла

int 21h; создать / открыть файл

mov bx, ax; идентификатор файла - в ВХ

mov ah, 40h; Функция DOS 40h

mov cx, bfsize; размер BMP-файла

mov ds, word ptr buffer_seg

mov dx, 0; DS:DX - буфер для файла

int 21h; запись в файл или устройство

mov ah, 68h; сбросить буфера на диск

int 21h

mov ah, 3Eh; закрыть файл

int 21h

call ems_reset

ret

do_io endp

; Процедура ems_init,

; если буфер расположен в EMS, подготавливает его для чтения / записи

ems_init proc near

cmp dx, word ptr ems_handle; если не используется EMS

cmp dx, 0; (EMS-идентификаторы начинаются с 1),

je ems_init_exit; ничего не делать

mov ax, 4700h; Функция EMS 47h

int 67h; сохранить EMS-контекст

mov ax, 4100h; Функция EMS 41h

int 67h; определить адрес окна EMS

mov word ptr buffer_seg, bx; сохранить его

mov ax, 4400h; Функция EMS 44h

mov bx, 0; начиная со страницы 0,

int 67h; отобразить страницы EMS в окно

mov ax, 4401h

inc bx

int 67h; страница 1

mov ax, 4402h

inc bx

int 67h; страница 2

mov ax, 4403h

inc bx

int 67h; страница 3

ems_init_exit:

ret

ems_init endp

; Процедура ems_reset

; восстанавливает состояние EMS

ems_reset proc near

mov dx, word ptr cs:ems_handle

cmp dx, 0

je ems_reset_exit

mov ax, 4800h; Функция EMS 48h

int 67h; восстановить EMS-контекст

ems_reset_exit:

ret

ems_reset endp

; Процедура safe_check

; возвращает CF = 0, если в данный момент можно пользоваться функциями DOS,

; и CF = 1, если нельзя

safe_check proc near

push es

push cs

pop ds

les di, dword ptr in_dos_addr; адрес флагов занятости DOS,

cmp word ptr es: [di], 0; если один из них не 0,

pop es

jne safe_check_failed; пользоваться DOS нельзя,

cmp byte ptr bios_busy, 0; если выполняется прерывание 13h,

jne safe_check_failed; тоже нельзя

clc; CF = 0

ret

safe_check_failed:

stc; CF = 1

ret

safe_check endp

in_dos_addr dd?; адрес флагов занятости DOS

io_needed db 0; 1, если надо записать файл на диск

bios_busy db 0; 1, если выполняется прерывание INT 13h

buffer_seg dw 0; сегментный адрес буфера для файла

ems_handle dw 0; идентификатор EMS

filespec db 'scrgrb.bmp', 0; имя файла

; Обработчик INT 2Dh

hw_reset2D: retf

int2Dh_handler proc far

jmp short actual_int2Dh_handler; пропустить ISP

old_int2Dh dd?

dw 424Bh

db 00h

jmp short hw_reset2D

db 7 dup (0)

actual_int2Dh_handler:; собственно обработчик

db 80h, 0FCh; начало команды CMP АН, число

mux_id db?; идентификатор программы,

je its_us; если вызывают с чужим АН - это не нас

jmp dword ptr cs:old_int2Dh

its_us:

cmp al, 06; функции AMIS 06h и выше

jae int2D_no; не поддерживаются

cbw; AX = номер функции

mov di, ax; DI = номер функции

shl di, 1; * 2, так как jumptable - таблица слов

jmp word ptr cs:jumptable[di]; переход на обработчик функции

jumptable dw offset int2D_00, offset int2D_no

dw offset int2D_02, offset int2D_no

dw offset int2D_04, offset int2D_05

int2D_00:; проверка наличия

mov al, 0FFh; этот номер занят

mov cx, 0100h; номер версии программы 1.0

push cs

pop dx; DX:DI - адрес AMIS-сигнатуры

mov di, offset amis_sign

iret

int2D_no:; неподдерживаемая функция

mov al, 00h; функция не поддерживается

iret

unload_failed:; сюда передается управление, если хоть один из векторов

; прерываний был перехвачен кем-то после нас

mov al, 01h; выгрузка программы не удалась

iret

int2D_02:; выгрузка программы из памяти

cli; критический участок

push 0

pop ds; DS - сегментный адрес таблицы векторов прерываний

mov ax, cs; наш сегментный адрес

; проверить, все ли перехваченные прерывания по-прежнему указывают на нас,

; обычно достаточно проверить только сегментные адреса (DOS не загрузит другую

; программу с нашим сегментным адресом)

cmp ax, word ptr ds: [09h*4+2]

jne unload_failed

cmp ax, word ptr ds: [13h*4+2]

jne unload_failed

cmp ax, word ptr ds: [08h*4+2]

jne unload_failed

cmp ax, word ptr ds: [28h*4+2]

jne unload_failed

cmp ax, word ptr ds: [2Dh*4+2]

jne unload_failed

push bx; адрес возврата - в стек

push dx

; восстановить старые обработчики прерываний

mov ax, 2509h

lds dx, dword ptr cs:old_int09h

int 21h

mov ax, 2513h

lds dx, dword ptr cs:old_int13h

int 21h

mov ax, 2508h

lds dx, dword ptr cs:old_int08h

int 21h

mov ax, 2528h

lds dx, dword ptr cs:old_int28h

int 21h

mov ax, 252Dh

lds dx, dword ptr cs:old_int2Dh

int 21h

mov dx, word ptr cs:ems_handle; если используется EMS

cmp dx, 0

je no_ems_to_unhook

mov ax, 4500h; функция EMS 45h

int 67h; освободить выделенную память

jmp short ems_unhooked

no_ems_to_unhook:

ems_unhooked:

; собственно выгрузка резидента

mov ah, 51h; Функция DOS 51h

int 21h; получить сегментный адрес PSP

; прерванного процесса (в данном случае

; PSP - копии нашей программы,

; запущенной с ключом /u)

mov word ptr cs: [16h], bx; поместить его в поле

; «сегментный адрес предка» в нашем PSP

pop dx; восстановить адрес возврата из стека

pop bx

mov word ptr cs: [0Ch], dx; и поместить его в поле

mov word ptr cs: [0Ah], bx; «адрес перехода при

; завершении программы» в нашем PSP

pop bx; BX = наш сегментный адрес PSP

mov ah, 50h; Функция DOS 50h

int 21h; установить текущий PSP

; теперь DOS считает наш резидент текущей программой, а scrgrb.com /u -

; вызвавшим его процессом, которому и передаст управление после вызова

; следующей функции

mov ax, 4CFFh; Функция DOS 4Ch

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

int2D_04:; получить список перехваченных прерываний

mov dx, cs; список в DX:BX

mov bx, offset amis_hooklist

iret

int2D_05:; получить список «горячих» клавиш

mov al, 0FFh; функция поддерживается

mov dx, cs; список в DX:BX

mov bx, offset amis_hotkeys

iret

int2Dh_handler endp

; AMIS: сигнатура для резидентной программы

amis_sign db «Cubbi…»; 8 байт

db «ScrnGrab»; 8 байт

db «Simple screen grabber using EMS», 0

; AMIS: список перехваченных прерываний

amis_hooklist db 09h

dw offset int09h_handler

db 08h

dw offset int08h_handler

db 28h

dw offset int28h_handler

db 2Dh

dw offset int2Dh_handler

; AMIS: список «горячих» клавиш

amis_hotkeys db 1

db 1

db 22h; скан-код клавиши (G)

dw 08h; требуемые флаги клавиатуры

dw 0

db 1

; конец резидентной части

; начало процедуры инициализации

initialize proc near

jmp short initialize_entry_point

; пропустить различные варианты выхода без установки резидента,

; помещенные здесь потому, что на них передают управление

; команды условного перехода, имеющие короткий радиус действия

exit_with_message:

mov ah, 9; функция вывода строки на экран

int 21h

ret; выход из программы

already_loaded:; если программа уже загружена в память

cmp byte ptr unloading, 1; если мы не были вызваны с /u

je do_unload

mov dx, offset already_msg

jmp short exit_with_message

no_more_mux:; если свободный идентификатор INT 2Dh не найден

mov dx, offset no_more_mux_msg

jmp short exit_with_message

cant_unload1:; если нельзя выгрузить программу

mov dx, offset cant_unload1_msg

jmp short exit_with_message

do_unload:; выгрузка резидента: при передаче управления сюда АН содержит

; идентификатор программы - 1

inc ah

mov al, 02h; AMIS-функция выгрузки резидента

mov dx, es; адрес возврата

mov bx, offset exit_point; в DX:BX

int 2Dh; вызов нашего резидента через мультиплексор

push cs; если управление пришло сюда -

; выгрузка не произошла

pop ds

mov dx, offset cant_unload2_msg

jmp short exit_with_message

exit_point:; если управление пришло сюда -

push cs; выгрузка произошла

pop ds

mov dx, offset unloaded_msg

push 0; чтобы сработала команда RET для выхода

jmp short exit_with_message

initialize_entry_point:; сюда передается управление в самом начале

cld

cmp byte ptr cmd_line[1], '/'

jne not_unload

cmp byte ptr cmd_line[2], 'u'; если нас вызвали с /u

jne not_unload

mov byte ptr unloading, 1; выгрузить резидент

not_unload:

mov ah, 9

mov dx, offset usage; вывод строки с информацией о программе

int 21h

mov ah, - 1; сканирование от FFh до 01h

more_mux:

mov al, 00h; функция AMIS 00h -

; проверка наличия резидента

int 2Dh; мультиплексорное прерывание

cmp al, 00h; если идентификатор свободен,

jne not_free

mov byte ptr mux_id, ah; вписать его сразу в код обработчика,

jmp short next_mux

not_free:

mov es, dx; иначе - ES:DI = адрес AMIS-сигнатуры

; вызвавшей программы

mov si, offset amis_sign; DS:SI = адрес нашей сигнатуры

mov cx, 16; сравнить первые 16 байт,

repe cmpsb

jcxz already_loaded; если они не совпадают,

next_mux:

dec ah; перейти к следующему идентификатору,

jnz more_mux; если это 0

free_mux_found:

cmp byte ptr unloading, 1; и если нас вызвали для выгрузки,

je cant_unload1; а мы пришли сюда - программы нет в

; памяти,

cmp byte ptr mux_id, 0; если при этом mux_id все еще 0,

je no_more_mux; идентификаторы кончились

; проверка наличия устройства ЕММХХХХ0

mov dx, offset ems_driver

mov ax, 3D00h

int 21h; открыть файл / устройство

jc no_emmx

mov bx, ax

mov ax, 4400h

int 21h; IOCTL: получить состояние файла / устройства

jc no_ems

test dx, 80h; если старший бит DX = 0, ЕММХХХХ0 - файл

jz no_ems

; выделить память под буфер в EMS

mov ax, 4100h; функция EMS 41h

int 67h; получить адрес окна EMS

mov bp, bx; сохранить его пока в ВР

mov ax, 4300h; Функция EMS 43h

mov bx, 4; нам надо 4 * 16 Кб

int 67h; выделить EMS-память (идентификатор в DХ),

cmp ah, 0; если произошла ошибка (нехватка памяти?),

jnz ems_failed; не будем пользоваться EMS,

mov word ptr ems_handle, dx; иначе: сохранить идентификатор

; для резидента

mov ax, 4400h; Функция 44h - отобразить

mov bx, 0; EMS-страницы в окно

int 67h; страница 0

mov ax, 4401h

inc bx

int 67h; страница 1

mov ax, 4402h

inc bx

int 67h; страница 2

mov ax, 4403h

inc bx

int 67h; страница 3

mov dx, offset ems_msg; вывести сообщение об установке в EMS

jmp short ems_used

ems_failed:

no_ems:; если EMS нет или он не работает,

mov ah, 3Eh

int 21h; закрыть файл / устройство ЕММХХХХ0,

no_emmx:

; занять общую память

mov ah, 9

mov dx, offset conv_msg; вывод сообщения об этом

int 21h

mov sp, length_of_program+100h+200h; перенести стек

mov ah, 4Ah; Функция DOS 4Ah

next_segment = length_of_program+100h+200h+0Fh

next_segment = next_segment/16; такая запись нужна только для

; WASM, остальным ассемблерам это

; можно было записать в одну строчку

mov bx, next_segment; уменьшить занятую память, оставив

; текущую длину нашей программы + 100h

; на PSP +200h на стек

int 21h

mov ah, 48h; Функция 48h - выделить память

bfsize_p = bfsize+0Fh

bfsize_p = bfsize_p/16

mov bx, bfsize_p; размер BMP-файла 320x200x256 в 16-байтных

int 21h; параграфах

ems_used:

mov word ptr buffer_seg, ax; сохранить адрес буфера для резидента

; скопировать заголовок BMP-файла в начало буфера

mov cx, BMP_header_length

mov si, offset BMP_header

mov di, 0

mov es, ax

rep movsb

; получить адреса флага занятости DOS и флага критической ошибки (считая, что

; версия DOS старше 3.0)

mov ah, 34 л; Функция 34h - получить флаг занятости

int 21h

dec bx; уменьшить адрес на 1, чтобы он указывал

; на флаг критической ошибки,

mov word ptr in_dos_addr, bx

mov word ptr in_dos_addr+2, es; и сохранить его для резидента

; перехват прерываний

mov ax, 352Dh; АН = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 2Dh

mov word ptr old_int2Dh, bx; и поместить его в old_int2Dh

mov word ptr old_int2Dh+2, es

mov ax, 3528h; AH = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 28h

mov word ptr old_int28h, bx; и поместить его в old_int28h

mov word ptr old_int28h+2, es

mov ax, 3508h; AH = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 08h

mov word ptr old_int08h, bx; и поместить его в old_int08h

mov word ptr old_int08h+2, es

mov ax, 3513h; AH = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 13h

mov word ptr old_int13h, bx; и поместить его в old_int13h

mov word ptr old_int13h+2, es

mov ax, 3509h; AH = 35h, AL = номер прерывания

int 21h; получить адрес обработчика INT 09h

mov word ptr old_int09h, bx; и поместить его в old_int09h

mov word ptr old_int09h+2, es

mov ax, 252Dh; AH = 25h, AL = номер прерывания

mov dx, offset int2Dh_handler; DS:DX - адрес обработчика

int 21h; установить новый обработчик INT 2Dh

mov ax, 2528h; AH = 25h, AL = номер прерывания

mov dx, offset int28h_handler; DS:DX - адрес обработчика

int 21h; установить новый обработчик INT 28h

mov ax, 2508h; AH = 25h, AL = номер прерывания

mov dx, offset int08h_handler; DS:DX - адрес обработчика

int 21h; установить новый обработчик INT 08h

mov ax, 2513h; AH = 25h, AL = номер прерывания

mov dx, offset int13h_handler; DS:DX - адрес обработчика

int 21h; установить новый обработчик INT 13h

mov ax, 2509h; AH = 25h, AL = номер прерывания

mov dx, offset int09h_handler; DS:DX - адрес обработчика

int 21h; установить новый обработчик INT 09h

; освободить память из-под окружения DOS

mov ah, 49h; Функция DOS 49h

mov es, word ptr envseg; ES = сегментный адрес окружения DOS

int 21h; освободить память

; оставить программу резидентной

mov dx, offset initialize; DX - адрес первого байта за концом

; резидентной части

int 27h; завершить выполнение, оставшись

; резидентом

initialize endp

ems_driver db 'EMMXXXX0', 0; имя EMS-драйвера для проверки

; текст, который выдает программа при запуске:

usage db 'Простая программа для копирования экрана только из'

db ' видеорежима 13h', 0Dh, 0Ah

db ' Alt-G - записать копию экрана в scrgrb.bmp'

db 0Dh, 0Ah

db ' scrgrb.com /u - выгрузиться из памяти', 0Dh, 0Ah

db '$'

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

ems_msg db 'Загружена в EMS', 0Dh, 0Ah, '$'

conv_msg db 'He загружена в EMS', 0Dh, 0Ah, '$'

unloaded_msg db 'Программа успешно выгружена из памяти', 0Dh, 0Ah, '$'

; тексты, которые выдает программа при ошибках:

already_msg db 'Ошибка: Программа уже загружена', 0Dh, 0Ah, '$'

no_more_mux_msg db 'Ошибка: Слишком много резидентных программ'

db 0Dh, 0Ah, '$'

cant_unload1_msg db 'Ошибка: Программа не обнаружена в памяти', 0Dh, 0Ah, '$'

cant_unload2_msg db 'Ошибка: Другая программа перехватила прерывания'

db 0Dh, 0Ah, '$'

unloading db 0; 1, если нас запустили с ключом /u

; BMP-файл (для изображения 320x200x256)

BMP_header label byte

; файловый заголовок

BMP_file_header db «BM»; сигнатура

dd bfsize; размер файла

dw 0,0; 0

dd bfoffbits; адрес начала BMP_data

; информационный заголовок

BMP_info_header dd bi_size; размер BMP_info_header

dd 320; ширина

dd 200; высота

dw 1; число цветовых плоскостей

dw 8; число бит на пиксель

dd 0; метод сжатия данных

dd 320*200; размер данных

dd 0B13h; разрешение по X (пиксель на метр)

dd 0B13h; разрешение по Y (пиксель на метр)

dd 0; число используемых цветов (0 - все)

dd 0; число важных цветов (0 - все)

bi_size = $-BMP_info_header; размер BMP_info_header

BMP_header_length = $-BMP_header; размер обоих заголовков

bfoffbits = $-BMP_file_header+256*4; размер заголовков + размер палитры

bfsize = $-BMP_file_header+256*4+320*200; размер заголовков +

; размер палитры + размер данных

length_of_program = $-start

end start

В этом примере, достаточно сложном из-за необходимости избегать всех возможностей повторного вызова прерываний DOS и BIOS, добавилась еще одна мера предосторожности - сохранение состояния EMS-памяти перед работой с ней и восстановление в исходное состояние. Действительно, если наш резидент активируется в тот момент, когда какая-то программа работает с EMS, и не выполнит это требование, программа будет читать / писать уже не в свои EMS-страницы, а в наши. Аналогичные предосторожности следует предпринимать всякий раз, когда вызываются функции, затрагивающие какие-нибудь глобальные структуры данных. Например: функции поиска файлов используют буфер DTA, адрес которого надо сохранить (функция DOS 2Fh), затем создать собственный (функция DOS 1Ah) и в конце восстановить DTA прерванного процесса по сохраненному адресу (функция 1Ah). Таким образом надо сохранять / восстанавливать состояние адресной линии А20 (функции XMS 07h и 03h), если резидентная программа хранит часть своих данных или кода в области HMA, сохранять состояние драйвера мыши (INT 33h, функции 17h и 18h), сохранять информацию о последней ошибке DOS (функции DOS 59h и 5D0Ah), и так с каждым ресурсом, который затрагивает резидентная программа. Писать полноценные резидентные программы в DOS сложнее всего, но, если не выходить за рамки реального режима, это - самое эффективное средство управления системой и реализации всего, что только можно реализовать в DOS.

2. Определить значение нескольких векторов, установить новое значение, в процедуре прерывания обработать прерывание от клавиатуры.

; prg15_1.asm

<2> MASM

<3> MODEL small; модель памяти

<4> STACK 256; размер стека

<5> .486p

<6> delay macro time

<7> local ext, iter

<8>; макрос задержки

<9>; На входе - значение переменной задержки (в мкс)

<10> push cx

<11> mov cx, time

<12> ext:

<13> push cx

<14>; в cx одна мкс, это значение можно

<15>; поменять в зависимости от производительности процессора

<16> mov cx, 5000

<17> iter:

<18> loop iter

<19> pop cx

<20> loop ext

<21> pop cx

<22> endm; конец макроса

<23> .data

<24> tonelow dw 2651; нижняя граница звучания 450 Гц

<25> cnt db 0; счетчик для выхода из программы

<26> temp dw?; верхняя граница звучания

<27> old_off8 dw 0; для хранения старых значений вектора

<28> old_seg8 dw 0; сегмент и смещение

<29> time_1ch dw 0; переменная для пересчета

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

<31> off_1ch equ 1ch*4; смещение вектора 1ch в ТВП

<32> off_0ffh equ 0ffh*4; смещение вектора ffh в ТВП

<33> char db «0»; символ для вывода на экран

<34> maskf db 07h; маска вывода символов на экран

<35> position dw 2000; позиция на экране - почти центр

<36> main proc

<37> mov ax,@data

<38> mov ds, ax

<39> xor ax, ax

<40> cli; запрет аппаратных прерываний на время

<41>; замены векторов прерываний

<42>; замена старого вектора 1ch на адрес new_1ch

<43>; настройка es на начало таблицы векторов

<44>; прерываний - в реальном режиме:

<45> mov ax, 0

<46> mov es, ax

<47>; сохранить старый вектор

<48> mov ax, es: [off_1ch]; смещение старого вектора 1ch в ax

<49> mov old_off8, ax; сохранение смещения в old_off8

<50> mov ax, es: [off_1ch+2]; сегмент старого вектора 1ch в ax

<51> mov old_seg8, ax; сохранение сегмента в old_seg8

<52>; записать новый вектор в таблицу векторов прерываний

<53> mov ax, offset new_1ch; смещение нового обработчика в ax

<54> mov es:off_1ch, ax

<55> push cs

<56> pop ax; настройка ax на cs

<57> mov es:off_1ch+2, ax; запись сегмента

<58>; инициализировать вектор пользовательского прерывания 0ffh

<59> mov ax, offset new_0ffh

<60> mov es:off_0ffh, ax; прерывание 0ffh

<61> push cs

<62> pop ax

<63> mov es:off_0ffh+2, ax

<64> sti; разрешение аппаратных прерываний

<65>; задержка, чтобы новый обработчик таймера вывел символы на экран

<66> delay 3500

<67>; завершение программы

<68> int 0ffh

<69> exit:

<70> mov ax, 4c00h

<71> int 21h

<72> main endp

<73> new_1ch proc; новый обработчик прерывания от таймера

<74>; сохранение в стеке используемых регистров

<75> push ax

<76> push bx

<77> push es

<78> push ds

<79>; настройка ds на cs

<80> push cs

<81> pop ds

<82>; запись в es адреса начала видеопамяти - B800:0000

<83> mov ax, 0b800h

<84> mov es, ax

<85> mov al, char; символ в al

<86> mov ah, maskf; маску вывода - в ah

<87> mov bx, position; позицию на экране - в bx

<88> mov es: [bx], ax; вывод символа в центр экрана

<89> add bx, 2; увеличение позиции

<90> mov position, bx; сохранение новой позиции

<91> inc char; следующий символ

<92>; восстановление используемых регистров:

<93> pop ds

<94> pop es

<95> pop bx

<96> pop ax

<97> iret; возврат из прерывания

<98> new_1ch endp; конец обработчика

<99> new_0ffh proc; новый обработчик пользовательского прерывания

<100> sirena:

<101>; сохранение в стеке используемых регистров

<102> push ax

<103> push bx

<104>; проверка для пересчета на 4:

<105> test time_1ch, 03h

<106> jnz leave_it; если два правых бита не 11, то на выход,; иначе:

<107> go:

<108> mov ax, 0B06h; заносим слово состояния 110110110b

<109>; (0В6h) - выбираем второй канал порта 43h (динамик)

<110> out 43h, ax; в порт 43h

<111> in al, 61h; получим значение порта 61h в al

<112> or al, 3; инициализируем динамик - подаем ток

<113> out 61h, al; в порт 61h

<114> mov cx, 2083; количество шагов

<115> musicup:

<116>; значение нижней границы частоты в ax (1193000/2651=450 Гц),

<117>; где 1193000 - частота динамика

<118> mov ax, tonelow

<119> out 42h, al; в порт 42h - младшее слово ax:al

<120> mov al, ah; обмен между al и ah

<121> out 42h, al; в порте 42h уже старшее слово ax:ah

<122> add tonelow, 1; увеличение частоты

<123> delay 1; задержка на 1 мкс

<124> mov dx, tonelow; текущее значение частоты - в dx

<125> mov temp, dx; в temp - верхнее значение частоты

<126> loop musicup; повторить цикл повышения

<127> mov cx, 2083

<128> musicdown:

<129> mov ax, temp; верхнее значение частоты - в ax

<130> out 42h, al; младший байт ax:al в порт 42h

<131> mov al, ah; обмен между al и ah

<132> out 42h, al; старший байт ax:ah в порт 42h

<133> sub temp, 1; уменьшение частоты

<134> delay 1; задержка на 1 мкс

<135> loop musicdown; повторить цикл понижения

<136> nosound:

<137> in al, 61h; значение порта 61h - в al

<138>; слово состояния 0fch - выключение динамика и таймера

<139> and al, 0fch

<140> out 61h, al; в порт 61h

<141> mov dx, 2651; для последующих циклов

<142> mov tonelow, dx

<143> inc cnt; инкремент количества проходов

<144> cmp cnt, 2; если сирена не звучала двух; раз - повторный запуск

<145> jne go

<146> leave_it:; выход

<147> inc time_1ch; пересчет на 4

<148>; восстановление используемых регистров

<149> pop bx

<150> pop ax

<151>; восстановление вектора прерывания от таймера

<152> cli; запрет аппаратных прерываний

<153> xor ax, ax; снова настройка es на начало таблицы

<154> mov es, ax; векторов прерываний

<155> mov ax, old_off8; запись в таблицу смещения старого

<156> mov es:off_1ch, ax; обработчика прерывания от таймера

<157> mov ax, old_seg8; запись сегмента

<158> mov es:off_1ch+2, ax

<159> sti; разрешение аппаратных прерываний

<160> iret; возврат из прерывания

<161> new_0ffh endp; конец обработчика

<162> end main; конец программы

Список используемой литературы

Бэрри Н. Компьютерные сети. Пер. с англ. - М.: БИНОМ. - 1995. - 400 с.

Джамса К., Лалани С., Уикли С. Программирование в WWW для профессионалов. - Минск. - Попурри. - 1997. - 631 с.

Кент П. World Wide Web: Пер. с англ. - М.: Компьютер. - 1996. - 311 с.

Кулаков Ю.А. Компьютерные сети. - Киев. - 1998. - 384 с.

Компьютерные сети. Принципы, технологии, протоколы/В.Г. Олифер, Н.А. Олифер. - СПб: Питер, 2001. - 672 с.

Максимов Н.В., Партыка Т.Л., Попов И.И. Технические средства информатизации: Учебник. - М.: ФОРУМ: ИНФРА-М, 2005. - 576 с.: ил. - (Профессиональное образование)

Милославская Н.Г., Толстой А.И. Интрасети: доступ в Internet. Защита: Учеб. пособие для вузов. - М.: ЮНИТИ - ДАНА, 200, 527 с.

Колесников Internet: для пользователя. - К.: Издательская группа BHV, 2000.-304 с.

Новомлинский Л. Интернет - торговля. Часть 1/ Сети и системы связи. 1998 - №8.

Новомлинский Л. Интернет - торговля. Часть 2/ Сети и системы связи. 1998 - №9.

Пятибратов А.П. Вычислительные машины, сети и телекоммуникации/ Пятибратов А.П., Гудыно Л.П. - М.: Финансы и статистика. - 1998. - 400 с.

Сеть Internet. Применение в науке и бизнесе/ Горностаев Ю.М. и др. - М.: Россия - 1994. - 136 с.

Сеть Internet./ Горностаев Ю.М. и др. - М.: Россия. - 1993. - 88 с.

Сорокин Л. Аукционы в Интернате - будущее электронной коммерции // Мир электронной коммерции. - 2000. - №1.

Информатика: Учебник. - 3-е перераб. изд. / Под ред. проф. Н.В. Макаровой. - М.: Финансы и статистика, 2000. - 768 с.: ил.

Размещено на Allbest.ru


Подобные документы

  • Проектирование механизма обработки прерываний. Контроллер прерываний Intel 82C59A. Ввод-вывод по прерыванию. Программируемый контроллер интерфейса Intel 82C55A. Роль процессора в обработке прерывания ввода-вывода. Обзор алгоритма обработки прерывания.

    контрольная работа [8,0 M], добавлен 19.05.2010

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

    реферат [192,2 K], добавлен 10.11.2014

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

    реферат [995,8 K], добавлен 22.06.2011

  • Прерывание и его природа. Контролер прерываний. Обработка прерываний в реальном режиме. Характеристики реального режима работы микропроцессора. Схема обработки прерываний в реальном режиме. Написание собственного прерывания. Разработка в общем случае.

    доклад [347,0 K], добавлен 22.09.2008

  • Использование недостaтков, присущих различным типам сетей и протоколам без шифровaния дaнных. Куки, аутентификация, шифрование, сниффинг, спуфинг. Метод компромиентации системы. Варианты MITM-атаки. Перехват сессии с использованием утилиты Cookie Cadger.

    курсовая работа [1,8 M], добавлен 28.05.2015

  • Принципы и алгоритмы обработки прерываний. Набор действий по реализации этапов обработки прерываний микропроцессора. Разработка структуры и алгоритма резидентной программы. Реализация программы на языке Ассемблер, методы её отладки и тестирования.

    курсовая работа [348,7 K], добавлен 22.12.2014

  • Принципы организации и особенности обработки прерываний на основе контроллера 8259A. Общая характеристика аппаратных средств системы прерываний PIC (Programmable Interrupt Controller). История разработки и порядок работы с технологией Plag and Play.

    курсовая работа [305,1 K], добавлен 29.07.2010

  • Архитектура микроконтроллеров семейства Mega. Организация памяти. Способы адресации памяти данных. Энергонезависимая память данных. Таблица векторов прерываний. Счетчик команд и выполнение программы. Абсолютный вызов подпрограммы. Сторожевой таймер.

    дипломная работа [213,9 K], добавлен 02.04.2009

  • Рассмотрение основных особенностей компьютерной программы Assembler: функции, структурное описание. Характеристика собственных векторов обработчиков прерываний. Div64 как функция-вычислитель, реализующая операцию деления знаковых чисел в формате 64:16.

    контрольная работа [224,7 K], добавлен 11.03.2013

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

    курсовая работа [349,3 K], добавлен 18.06.2009

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.