Скачиваний:
27
Добавлен:
15.09.2014
Размер:
55.65 Кб
Скачать

ПРИМЕРЫ h4.Y {COLOR: RED; font-family: arial} ПРИМЕРЫ ПРОГРАММ Полный листинг программы поиска подключенных жестких дисков по каналам 1 и 2. После запуска программа выводит на экран некоторые параметры найденных жестких дисков системы, среди которых число логических цилиндров, головок, секторов, серийный номер, модель и др. Программу рекомендуется запускать в режиме эмуляции MS-DOS. ; Автор текста программы Кулаков Владимир Геннадьевич. IDEAL P386 LOCALS MODEL MEDIUM ; Подключить файл мнемонических обозначений ; кодов управляющих клавиш include "lst_1_03.inc" ; Подключить файл мнемонических обозначений цветов include "lst_1_05.inc" DATASEG ; Текстовые сообщения Txt1 DB LIGHTCYAN,0,26,"ИДЕНТИФИКАЦИЯ ЖЕСТКИХ ДИСКОВ",0 DB YELLOW,24,35,"Ждите ...",0 Txt2 DB 2,27,"На канале найден диск .",0 DB 4,25,"Параметры обнаруженного диска:",0 DB 6,22,"Общая информация:",0 DB 7,12,"Число логических цилиндров:",0 DB 8,14,"Число логических головок:",0 DB 9,13,"Число логических секторов:",0 DB 10,24,"Серийный номер:",0 DB 11,32,"Модель:",0 DB 12,8,"Макс. кол-во секторов за сеанс:",0 DB 13,27,"Возможности:",0 DB 14,10,"Текущее число лог. цилиндров:",0 DB 15,12,"Текущее число лог. головок:",0 DB 16,11,"Текущее число лог. секторов:",0 DB 17,13,"Текущая емкость, секторов:",0 DB 18,11,"Число секторов в режиме LBA:",0 DB 19,13,"Поддерживаемые режимы DMA:",0 DB 20,17,"Улучшенные режимы PIO:",0 Txt3 DB LIGHTGREEN DB 12,24,"Поиск завершен, больше нет дисков",0 AnyK DB YELLOW,24,29,"Нажмите любую клавишу",0 ENDS SEGMENT sseg para stack 'STACK' DB 400h DUP(?) ENDS CODESEG ;***************************** ;* Основной модуль программы * ;***************************** PROC IdentifyDevices mov AX,DGROUP mov DS,AX ; Установить текстовый режим и очистить экран mov AX,3 int 10h ; Скрыть курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Вывести текстовые сообщения на экран mov SI,offset Txt1 call ShowColorString call ShowColorString ; Цикл опроса каналов mov [ChannelNumber],1 ; Опросить Master-диск @@AskMaster: call ClearPrevInfo mov [HDDNumber],0 call ReadHDD_ID cmp [HDDErrorCode],0 jne @@AskSlave call ShowHDD_ID ; Опросить Slave-диск @@AskSlave: call ClearPrevInfo mov [HDDNumber],1 call ReadHDD_ID cmp [HDDErrorCode],0 jne @@NextCannel call ShowHDD_ID @@NextCannel: inc [ChannelNumber] cmp [ChannelNumber],3 jb @@AskMaster @@End: ; Выдать сообщение о завершении поиска call ClearPrevInfo mov SI,offset Txt3 call ShowColorString call ShowColorString call GetChar ; Переустановить текстовый режим mov ax,3 int 10h ; Выход в DOS mov AH,4Ch int 21h ENDP IdentifyDevices ;************************************ ;* РАСШИФРОВКА ИДЕНТИФИКАТОРА ДИСКА * ;************************************ PROC ShowHDD_ID near pushad ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN mov CX,17 mov SI,offset Txt2 @@NextStr: call ShowString loop @@NextStr mov SI,offset AnyK call ShowColorString ; Установить белый цвет и черный фон mov [TextColorAndBackground],WHITE ; Вывести номер канала и номер диска mov [ScreenString],2 mov [ScreenColumn],37 mov AX,[ChannelNumber] call ShowDecWord mov [ScreenColumn],51 mov AL,[HDDNumber] call ShowDecByte ; Вывести отдельные поля идентификатора ; (только неспецифические) ; Общая информация mov [ScreenString],6 mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer] call ShowBinWord ; Число логических цилиндров inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+1*2] call ShowDecWord ; Число логических головок inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+3*2] call ShowDecWord ; Число логических секторов inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+6*2] call ShowDecWord ; Серийный номер mov AX,0B800h mov ES,AX mov SI,offset SectorDataBuffer add SI,10*2 mov DI,(10*80+40)*2 mov AH,[TextColorAndBackground] mov CX,10 @@NextWord1: mov DX,[SI] mov AL,DH stosw mov AL,DL stosw add SI,2 loop @@NextWord1 ; Номер модели mov SI,offset SectorDataBuffer add SI,27*2 mov DI,(11*80+40)*2 mov AH,[TextColorAndBackground] mov CX,20 @@NextWord2: mov DX,[SI] mov AL,DH stosw mov AL,DL stosw add SI,2 loop @@NextWord2 ; Макс. кол-во секторов за сеанс add [ScreenString],3 mov [ScreenColumn],40 mov AL,[SectorDataBuffer+47*2] call ShowDecByte ; Возможности inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+49*2] call ShowBinWord ; Значения слов 54-58 достоверны? test [word ptr SectorDataBuffer+53*2],1 jz @@NotValid5458 ; Текущее число логических цилиндров inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+54*2] call ShowDecWord ; Текущее число логических головок inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+55*2] call ShowDecWord ; Текущее число логических секторов inc [ScreenString] mov [ScreenColumn],40 mov AX,[word ptr SectorDataBuffer+56*2] call ShowDecWord ; Текущая емкость, секторов inc [ScreenString] mov [ScreenColumn],40 mov EAX,[dword ptr SectorDataBuffer+57*2] call ShowDecDWord @@NotValid5458: ; Число секторов в режиме LBA mov [ScreenString],18 mov [ScreenColumn],40 mov EAX,[dword ptr SectorDataBuffer+60*2] call ShowDecDWord ; Поддерживаемые режимы DMA inc [ScreenString] mov [ScreenColumn],40 mov AL,[SectorDataBuffer+63*2] call ShowByteBinCode ; Значения слов 64-70 достоверны? test [word ptr SectorDataBuffer+53*2],10b jz @@NotValid6470 ; Поддерживаемые режимы PIO inc [ScreenString] mov [ScreenColumn],40 mov AL,[SectorDataBuffer+64*2] call ShowByteBinCode @@NotValid6470: ; Ожидать нажатия любой клавиши call GetChar popad ret ENDP ShowHDD_ID ;************************************** ;* ОЧИСТИТЬ ЭКРАН И ВЫВЕСТИ ЗАГОЛОВКИ * ;************************************** PROC ClearPrevInfo near pushad ; Очистить экран call ClearScreen ; Вывести текстовые сообщения на экран mov SI,offset Txt1 call ShowColorString call ShowColorString popad ret ENDP ClearPrevInfo ENDS ; Подключить процедуры вывода данных на экран include "lst_1_02.inc" ; Подключить "математические" процедуры для перевода ; чисел из двоичного кода в десятичный include "lst_2_05.inc" ; Подключить процедуру непосредственного считывания ; сектора с жесткого диска include "lst_6_07.inc" END Данная программа подключает несколько внешних файлов: Файл lst_1_02.inc. Файл, содержащий процедуры ввода/вывода общего назначения для работы в цветном текстовом режиме. Файл lst_1_03.inc. Файл мнемонических обозначений кодов управляющих клавиш. Файл lst_1_05.inc. Файл мнемонических обозначений цветов. Файл lst_2_05.inc. Файл, содержащий набор подпрограмм, предназначенных для перевода целых и вещественных чисел из двоичной системы счисления в десятичную и наоборот. Файл lst_6_07.inc. Файл, содержащий процедуры для непосредственной работы с контроллером жестких дисков ATA.

Полный листинг программы просмотра секторов "ведущего" жесткого диска канала 1 в режиме LBA. После запуска программа выводит на экран содержимое секторов жесткого диска в ASCII-кодах. Пользователь может управлять номером просматриваемого сектора, нажимая клавиши "вверх" и "вниз". Программу рекомендуется запускать в режиме эмуляции MS-DOS. ; Автор текста программы Кулаков Владимир Геннадьевич. IDEAL P386 LOCALS MODEL MEDIUM ; Подключить файл мнемонических обозначений ; кодов управляющих клавиш include "lst_1_03.inc" ; Подключить файл мнемонических обозначений цветов include "lst_1_05.inc" DATASEG ; Текстовые сообщения Txt1 DB LIGHTCYAN,0,16,"Просмотр секторов " DB "жесткого диска в ASCII-кодах",0 DB LIGHTGREEN,5,8,"Сектор N :",0 DB LIGHTCYAN,17,8,"Управляющие клавиши:",0 DB YELLOW,24,27,"Нажмите управляющую клавишу",0 Txt2 DB 19,8,"Стрелка вниз - следующий сектор;",0 DB 20,8,"Стрелка вверх - предыдущий сектор;",0 DB 21,8,"Esc - выход.",0 Err1 DB LIGHTRED,12,21 DB "Master-диск на канале 1 не обнаружен.",0 Err2 DB LIGHTRED,12,24 DB "Диск не поддерживает режим LBA.",0 PBut DB YELLOW,24,29,"Нажмите любую клавишу",0 ENDS SEGMENT sseg para stack 'STACK' DB 400h DUP(?) ENDS CODESEG ;***************************** ;* Основной модуль программы * ;***************************** PROC ShowHDDSector mov AX,DGROUP mov DS,AX ; Установить текстовый режим и очистить экран mov AX,3 int 10h ; Скрыть курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Опросить Master-диск канала 1 mov [ChannelNumber],1 mov [HDDNumber],0 call ReadHDD_ID ; Диск подключен? cmp [HDDErrorCode],0 jne @@DiskNotFound ; Режим LBA поддерживается? cmp [dword ptr SectorDataBuffer+60*2],0 je @@LBANotSupported ; Вывести текстовые сообщения на экран mov CX,4 mov SI,offset Txt1 @@Txt1: call ShowColorString loop @@Txt1 ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN mov SI,offset Txt2 call ShowString call ShowString call ShowString ; Инициализируем переменные mov [HDDNumber],0 mov [dword ptr SectorAddress],0 mov AX,0B800h mov ES,AX ; ВНЕШНИЙ ЦИКЛ @@ReadSector: mov [ScreenString],5 mov [ScreenColumn],17 mov EAX,[SectorAddress] call ShowHexDword call ReadHDDSector mov DI,7*160+8*2 mov SI,offset SectorDataBuffer ; Задать для символов светло-голубой ; цвет и синий фон mov AH,LIGHTCYAN+BLUE*16 mov DX,8 ;счетчик строк @@OutNextString: mov CX,64 ;счетчик символов в строке @@OutNextChar: lodsb stosw loop @@OutNextChar add DI,16*2 dec DX jnz @@OutNextString @@GetCommand: ; Ожидаем ввода следующей команды call GetChar cmp AL,0 je @@TestCommandByte call Beep jmp short @@GetCommand @@TestCommandByte: cmp AH,B_Esc ;"Выход" je @@End @@TestDn: cmp AH,B_DN ;"Стрелка вниз" jne @@TestUp ; Увеличить на 1 номер сектора inc [dword ptr SectorAddress] jmp @@ReadSector @@TestUp: cmp AH,B_UP ;"Стрелка вверх" jne @@CommandError cmp [dword ptr SectorAddress],0 je @@CommandError ; Уменьшить на 1 номер сектора dec [dword ptr SectorAddress] jmp @@ReadSector @@CommandError: call Beep jmp @@GetCommand ; Обработка ошибок @@DiskNotFound: ; Сообщение "Диск не найден" mov SI,offset Err1 call ShowColorString mov SI,offset PBut call ShowColorString call GetChar jmp short @@End @@LBANotSupported: ; Сообщение "Диск не поддерживает LBA" mov SI,offset Err2 call ShowColorString mov SI,offset PBut call ShowColorString call GetChar ; Завершение работы программы @@End: ; Переустановить текстовый режим (очистить экран) mov ax,3 int 10h ; Выход в DOS mov AH,4Ch int 21h ENDP ShowHDDSector ENDS ; Подключить процедуры вывода данных на экран include "lst_1_02.inc" ; Подключить процедуру непосредственного считывания ; сектора с жесткого диска include "lst_6_07.inc" END Данная программа подключает несколько внешних файлов: Файл lst_1_02.inc. Файл, содержащий процедуры ввода/вывода общего назначения для работы в цветном текстовом режиме. Файл lst_1_03.inc. Файл мнемонических обозначений кодов управляющих клавиш. Файл lst_1_05.inc. Файл мнемонических обозначений цветов. Файл lst_6_07.inc. Файл, содержащий процедуры для непосредственной работы с контроллером жестких дисков ATA.

Полный листинг программы просмотра в режиме LBA параметров логических дисков на "ведущем" жестком диске канала 1. После запуска программа выдает таблицу разделов и загрузочную запись логических дисков на master-диске канала 1. Программу рекомендовано запускать в режиме эмуляции MS-DOS. ; Автор текста программы Кулаков Владимир Геннадьевич. IDEAL P386 LOCALS MODEL MEDIUM ; Подключить файл мнемонических обозначений ; кодов управляющих клавиш include "lst_1_03.inc" ; Подключить файл мнемонических обозначений цветов include "lst_1_05.inc" DATASEG ; Текстовые сообщения Txt00 DB YELLOW,24,29,"Нажмите любую клавишу",0 Txt01 DB YELLOW,0,30 DB "MASTER-ДИСК КАНАЛА 1",0 DB YELLOW,1,22 DB "ТАБЛИЦА РАЗДЕЛОВ ЛОГИЧЕСКОГО ДИСКА",0 Txt02 DB 8,1,"N",0 DB 8,4,"Тип",0 DB 8,9,"Призн.",0,9,9,"акт.",0 DB 8,16," Начало раздела",0 DB 9,17,"Гол.",0,9,24,"Цил.",0,9,31,"Сект.",0 DB 8,37," Конец раздела",0 DB 9,38,"Гол.",0,9,45,"Цил.",0,9,52,"Сект.",0 DB 8,58,"Номер нач.",0 DB 9,58,"сектора",0 DB 8,70,"Размер,",0 DB 9,70,"секторов",0 Txt11 DB YELLOW,0,19 DB "ЗАГРУЗОЧНАЯ ЗАПИСЬ ЛОГИЧЕСКОГО ДИСКА N",0 Txt12 DB 2,12,"Идентификатор изготовителя:",0 DB 3,22,"Байтов на сектор:",0 DB 4,19,"Секторов в кластере:",0 DB 5,14,"Число резервных секторов:",0 DB 6,23,"Число копий FAT:",0 DB 7,6,"Дескрипторов в корневом каталоге:",0 DB 8,14,"Число секторов в разделе:",0 DB 9,15,"Тип носителя информации:",0 DB 10,1,"Число секторов, занимаемых копией FAT:",0 DB 11,13,"Число секторов на дорожке:",0 DB 12,1,"Количество рабочих поверхностей диска:",0 DB 13,16,"Число скрытых секторов:",0 Txt13 DB 14,23,"Номер дисковода:",0 DB 15,15,"Номер логического диска:",0 DB 16,27,"Метка диска:",0 DB 17,9,"Аббревиатура файловой системы:",0 Txt14 DB 14,20,"Номер активной FAT:",0 DB 15,22,"Номер версии FAT:",0 DB 16,0 DB "Номер нач. кластера корневого каталога:",0 DB 17,8,"Номер сектора структуры FSINFO:",0 DB 18,4,"Номер сектора резервной копии Boot:",0 DB 19,23,"Номер дисковода:",0 DB 20,15,"Номер логического диска:",0 DB 21,27,"Метка диска:",0 DB 22,9,"Аббревиатура файловой системы:",0 Err1 DB LIGHTRED,12,22 DB "Master-диск на канале 1 не обнаружен",0 Err2 DB LIGHTRED,12,25 DB "Диск не поддерживает режим LBA",0 Err3 DB LIGHTRED,12,25 DB "Основной раздел DOS не найден",0 PBut DB YELLOW,24,29,"Нажмите любую клавишу",0 ; Номер раздела PartitionNumber DB ? ; Начальный сектор основного раздела DOS PriDOS_StartSector DD ? ; Начальный сектор расширенного раздела DOS ExtDOS_StartSector DD ? ; Начальный сектор текущего логического диска CurrentDrive_StartSector DD ? ; Линейный адрес загрузочного сектора BootSector DD ? ; Номер логического диска LogicalDriveNumber DB ? ; Тип текущей FAT (0 - FAT12, 1 - FAT16, 2 - FAT32) FATType DB ? ; Флаг присутствия в системе следующего диска NextDrivePresent DB ? ENDS SEGMENT sseg para stack 'STACK' DB 400h DUP(?) ENDS CODESEG ;***************************** ;* Основной модуль программы * ;***************************** PROC SearchLogicalDisks mov AX,DGROUP mov DS,AX ; Установить текстовый режим и очистить экран mov AX,3 int 10h ; Скрыть курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Опросить Master-диск канала 1 mov [ChannelNumber],1 mov [HDDNumber],0 call ReadHDD_ID ; Диск подключен? cmp [HDDErrorCode],0 jne @@DiskNotFound ; Режим LBA поддерживается? cmp [dword ptr SectorDataBuffer+60*2],0 je @@LBANotSupported ; Обнулить номер логического диска mov [LogicalDriveNumber],0 ; Прочитать MBR диска mov [CurrentDrive_StartSector],0 mov [dword ptr SectorAddress],0 call ReadHDDSector ; Отобразить таблицу разделов call ShowPartitionTable ; Найти и записать номера начальных секторов ; основного и расширенного разделов DOS mov [NextDrivePresent],0 mov SI,offset SectorDataBuffer add SI,1BEh ;смещение первой записи mov AL,[SI+4] ;извлечь тип раздела ; Проверить код основного раздела cmp AL,01h je @@PrimPartFound cmp AL,04h je @@PrimPartFound cmp AL,06h je @@PrimPartFound cmp AL,0Bh je @@PrimPartFound cmp AL,0Eh jne @@PrimPartNotFound @@PrimPartFound: ; Найден основной раздел, сохранить ; адрес его начального сектора mov EAX,[SI+8] ;извлечь адрес сектора mov [PriDOS_StartSector],EAX add SI,10h ;смещение второй записи mov AL,[SI+4] ;извлечь тип раздела ; Проверить код расширенного раздела cmp AL,05h je @@ExtPartFound cmp AL,0Ch je @@ExtPartFound cmp AL,0Fh jne @@NextDriveNotPresent0 @@ExtPartFound: ; Имеется расширенный раздел mov EAX,[SI+8] ;извлечь адрес сектора mov [ExtDOS_StartSector],EAX mov [NextDrivePresent],1 @@NextDriveNotPresent0: ; Прочитать BOOT-сектор основного раздела mov EAX,[PriDOS_StartSector] mov [SectorAddress],EAX call ReadHDDSector ; Отобразить данные BOOT-сектора основного раздела call DecodeBootSector ; Имеется следующий диск? cmp [NextDrivePresent],0 je @@End mov EAX,[ExtDOS_StartSector] mov [CurrentDrive_StartSector],EAX ; ЦИКЛ ОПРОСА ЛОГИЧЕСКИХ ДИСКОВ РАСШИРЕННОГО РАЗДЕЛА @@ReadSMBR: inc [LogicalDriveNumber] ; Прочитать очередной SMBR mov EAX,[CurrentDrive_StartSector] mov [BootSector],EAX mov [SectorAddress],EAX call ReadHDDSector ; Отобразить таблицу разделов call ShowPartitionTable ; Найти и записать номера начальных секторов mov [NextDrivePresent],0 mov SI,offset SectorDataBuffer add SI,1BEh ;смещение первой записи mov EAX,[SI+8] add [BootSector],EAX add SI,10h ;смещение второй записи mov EAX,[SI+8] cmp EAX,0 ;следующий диск присутствует? je @@NextDriveNotPresent1 ; Вычислить адрес SMBR следующего диска add EAX,[ExtDOS_StartSector] mov [CurrentDrive_StartSector],EAX ; Установить признак наличия следующего диска mov [NextDrivePresent],1 @@NextDriveNotPresent1: ; Прочитать BOOT-сектор логического диска mov EAX,[BootSector] mov [SectorAddress],EAX call ReadHDDSector ; Отобразить данные BOOT-сектора call DecodeBootSector ; Имеется следующий диск? cmp [NextDrivePresent],0 je @@End jmp @@ReadSMBR ; Обработка ошибок @@DiskNotFound: ; Сообщение "Диск не найден" mov SI,offset Err1 jmp short @@AllErr @@LBANotSupported: ; Сообщение "Диск не поддерживает LBA" mov SI,offset Err2 jmp short @@AllErr @@PrimPartNotFound: ; Сообщение "Не найден основной раздел" mov SI,offset Err3 @@AllErr: ; Общая часть обработки ошибок call ShowColorString mov SI,offset PBut call ShowColorString call GetChar ; Завершение работы программы @@End: ; Переустановить текстовый режим mov ax,3 int 10h ; Выход в DOS mov AH,4Ch int 21h ENDP SearchLogicalDisks ;***************************************** ;* ПРОЧИТАТЬ НУЛЕВОЙ СЕКТОР И ОТОБРАЗИТЬ * ;* НА ЭКРАН ТАБЛИЦУ РАЗДЕЛОВ * ;***************************************** PROC ShowPartitionTable near pushad push ES ; Очистить экран call ClearScreen ; Вывести текстовые сообщения на экран mov SI,offset Txt00 call ShowColorString mov SI,offset Txt01 call ShowColorString call ShowColorString mov [ScreenString],1 mov [ScreenColumn],57 mov [TextColorAndBackground],YELLOW mov AL,[LogicalDriveNumber] call ShowByteHexCode ; ЦИКЛ РИСОВАНИЯ ТАБЛИЦЫ mov AX,0B800h ;Настроить ES для прямого mov ES,AX ;вывода на экран mov DI,8*80*2 ;Начать вывод с 8-й строки mov AH,LIGHTBLUE ;Чертить синим цветом mov AL,0B3h ;Задать символ-разделитель mov DX,7 ;Задать общее число строк ; Отобразить символы-разделители колонок таблицы @@ac0: push DI add DI,3*2 mov [ES:DI],AX add DI,5*2 mov CX,8 @@ac1: mov [ES:DI],AX add DI,7*2 loop @@ac1 add DI,4*2 mov [ES:DI],AX pop DI add DI,80*2 dec DX jnz @@ac0 ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN ; Отобразить шапку таблицы mov CX,16 mov SI,offset Txt02 @@NextStr1: call ShowString loop @@NextStr1 ; ЦИКЛ ВЫВОДА ДАННЫХ ; Установить белый цвет и черный фон mov [TextColorAndBackground],WHITE ; Отобразить загрузочный сектор на экран mov [PartitionNumber],1 mov SI,offset SectorDataBuffer ; Прибавить смещение первой записи ; от начала сектора add SI,1BEh ; Задать начальную строку для вывода данных mov [ScreenString],11 @@ShS0: ; Отобразить порядковый номер раздела mov AL,[PartitionNumber] mov [ScreenColumn],0 call ShowByteHexCode ; Отобразить код типа раздела lodsb mov [ScreenColumn],11 call ShowByteHexCode ; Отобразить номер начальной поверхности раздела lodsb mov [ScreenColumn],18 call ShowByteHexCode ; Отобразить номер начального цилиндра ; и номер начального сектора раздела lodsw mov BL,AL ; Вычислить и отобразить номер цилиндра shr AL,6 xchg AL,AH mov [ScreenColumn],24 call ShowHexWord ; Вычислить и отобразить номер сектора mov AL,BL and AL,0111111b mov [ScreenColumn],32 call ShowByteHexCode ; Отобразить код признака активного раздела mov [ScreenColumn],5 lodsb call ShowByteHexCode ; Отобразить номер конечной поверхности раздела mov [ScreenColumn],39 lodsb call ShowByteHexCode ; Отобразить номер конечного цилиндра ; и номер конечного сектора раздела lodsw mov BL,AL ; Вычислить и отобразить номер цилиндра shr AL,6 xchg AL,AH mov [ScreenColumn],45 call ShowHexWord ; Вычислить и отобразить номер сектора mov AL,BL and AL,0111111b mov [ScreenColumn],53 call ShowByteHexCode ; Отобразить абсолютный номер начального сектора mov [ScreenColumn],59 mov EAX,[SI] add SI,4 call ShowHexDWord ; Отобразить размер раздела в секторах mov [ScreenColumn],70 mov EAX,[SI] add SI,4 call ShowHexDWord inc [ScreenString] inc [PartitionNumber] cmp [PartitionNumber],5 jb @@ShS0 ; Ожидаем нажатия клавиши call GetChar pop ES popad ret ENDP ShowPartitionTable ;********************************************** ;* ОТОБРАЗИТЬ ИНФОРМАЦИЮ ЗАГРУЗОЧНОГО СЕКТОРА * ;********************************************** PROC DecodeBootSector near pushad push ES ; Очистить экран call ClearScreen ; Вывести текстовые сообщения на экран mov SI,offset Txt00 call ShowColorString mov SI,offset Txt11 call ShowColorString ; Отобразить порядковый номер логического диска mov [ScreenString],0 mov [ScreenColumn],58 mov [TextColorAndBackground],YELLOW mov AL,[LogicalDriveNumber] call ShowByteHexCode ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN ; Отобразить названия общих полей mov CX,12 mov SI,offset Txt12 @@NextStr1: call ShowString loop @@NextStr1 ; Настроить ES для прямого вывода на экран mov AX,0B800h mov ES,AX ; Установить указатель на область данных mov SI,offset SectorDataBuffer ; Установить белый цвет и черный фон mov [TextColorAndBackground],WHITE ; ОБЩИЙ УЧАСТОК BOOT-СЕКТОРА ; Отобразить идентификатор OEM с 40-й позиции 2-й строки mov [ScreenString],2 mov [ScreenColumn],40 mov BX,3 mov CX,8 call ShowASCIIField ; Отобразить число байтов на сектор inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+0Bh] call ShowHexWord ; Отобразить число секторов в кластере inc [ScreenString] mov [ScreenColumn],40 mov AL,[SI+0Dh] call ShowByteHexCode ; Отобразить число резервных секторов inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+0Eh] call ShowHexWord ; Отобразить число копий FAT в разделе inc [ScreenString] mov [ScreenColumn],40 mov AL,[SI+10h] call ShowByteHexCode ; Отобразить число дескрипторов в корневом каталоге inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+11h] call ShowHexWord ; Отобразить число секторов в разделе inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+13h] cmp AX,0 je @@UseTotSec32 ;использовать BPB_TotSec32 call ShowHexWord @@UseTotSec32: ; Отобразить тип носителя информации inc [ScreenString] mov [ScreenColumn],40 mov AL,[SI+15h] call ShowByteHexCode ; Отобразить число секторов, занимаемых копией FAT inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+16h] cmp AX,0 je @@UseFATSz32 ;использовать BPB_FATSz32 call ShowHexWord @@UseFATSz32: ; Отобразить число секторов на дорожке inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+18h] call ShowHexWord ; Отобразить количество рабочих поверхностей диска inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+1Ah] call ShowHexWord ; Отобразить число скрытых секторов inc [ScreenString] mov [ScreenColumn],40 mov EAX,[SI+1Ch] call ShowHexDWord ; Отобразить число секторов в разделе mov [ScreenString],8 mov [ScreenColumn],40 mov EAX,[SI+20h] cmp EAX,0 je @@UseTotSec16 ;использовать BPB_TotSec16 call ShowHexDWord @@UseTotSec16: ; Проверить тип FAT текущего раздела mov [FATType],2 ; Если размер корневого сектора ; равен нулю - FAT32 cmp [word ptr SI+11h],0 je @@FAT32 mov [FATType],1 ; УЧАСТОК BOOT-СЕКТОРА, СПЕЦИФИЧЕСКИЙ ДЛЯ FAT12 И FAT16 ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN ; Отобразить названия полей, специфических ; для FAT12 и FAT16 mov CX,4 mov SI,offset Txt13 @@NextStr2: call ShowString loop @@NextStr2 ; Установить белый цвет и черный фон mov [TextColorAndBackground],WHITE ; Установить указатель на область данных mov SI,offset SectorDataBuffer ; Отобразить номер дисковода mov [ScreenString],14 mov [ScreenColumn],40 mov AL,[SI+24h] call ShowByteHexCode ; Отобразить номер логического диска inc [ScreenString] mov [ScreenColumn],40 mov EAX,[SI+27h] call ShowHexDWord ; Отобразить метку диска inc [ScreenString] mov [ScreenColumn],40 mov BX,2Bh mov CX,11 call ShowASCIIField ; Отобразить аббревиатуру файловой системы inc [ScreenString] mov [ScreenColumn],40 mov BX,36h mov CX,8 call ShowASCIIField jmp @@End @@FAT32: ; УЧАСТОК BOOT-СЕКТОРА, СПЕЦИФИЧЕСКИЙ ДЛЯ FAT32 ; Установить зеленый цвет и черный фон mov [TextColorAndBackground],LIGHTGREEN ; Отобразить названия полей, специфических FAT32 mov CX,9 mov SI,offset Txt14 @@NextStr3: call ShowString loop @@NextStr3 ; Установить белый цвет и черный фон mov [TextColorAndBackground],WHITE ; Установить указатель на область данных mov SI,offset SectorDataBuffer ; Отобразить число секторов, занимаемых копией FAT32 mov [ScreenString],10 mov [ScreenColumn],40 mov EAX,[SI+24h] call ShowHexDWord ; Отобразить номер активной FAT mov [ScreenString],14 mov [ScreenColumn],40 mov AX,[SI+28h] call ShowHexWord ; Отобразить код версии FAT inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+2Ah] call ShowHexWord ; Отобразить номер начального ; кластера корневого каталога inc [ScreenString] mov [ScreenColumn],40 mov EAX,[SI+2Ch] call ShowHexDWord ; Отобразить номер сектора структуры FSINFO inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+30h] call ShowHexWord ; Отобразить номер сектора резервной копии Boot-сектора inc [ScreenString] mov [ScreenColumn],40 mov AX,[SI+32h] call ShowHexWord ; Отобразить номер дисковода inc [ScreenString] mov [ScreenColumn],40 mov AL,[SI+40h] call ShowByteHexCode ; Отобразить номер логического диска inc [ScreenString] mov [ScreenColumn],40 mov EAX,[SI+43h] call ShowHexDWord ; Отобразить метку диска inc [ScreenString] mov [ScreenColumn],40 mov BX,47h mov CX,11 call ShowASCIIField ; Отобразить аббревиатуру файловой системы inc [ScreenString] mov [ScreenColumn],40 mov BX,52h mov CX,8 call ShowASCIIField @@End: call GetChar pop ES popad ret ENDP DecodeBootSector ;**************************************************** ;* ВЫВОД НА ЭКРАН ТЕКСТОВОГО ПОЛЯ ДАННЫХ * ;* Передаваемые параметры: * ;* DS:SI - указатель на структуру данных; * ;* BX - смещение поля от начала структуры; * ;* CX - длина поля в байтах. * ;* Цвет задается переменной TextColorAndBackground. * ;* Координаты позиции передаются через глобальные * ;* переменные ScreenString и ScreenColumn. * ;**************************************************** PROC ShowASCIIField near pusha push ES mov AX,0B800h ;Настроить ES для прямого mov ES,AX ;вывода на экран ; Установить указатель на начало поля add SI,BX ; Вычислить начальную позицию в видеопамяти mov AX,[ScreenString] mov DI,160 mul DI add AX,[ScreenColumn] add AX,[ScreenColumn] mov DI,AX ; Использовать цвет, заданный по умолчанию mov AH,[TextColorAndBackground] ; Вывести поле на экран @@NextChar: lodsb stosw loop @@NextChar pop ES popa ret ENDP ShowASCIIField ENDS ; Подключить процедуры вывода данных на экран include "lst_1_02.inc" ; Подключить процедуру непосредственного считывания ; сектора с жесткого диска include "lst_6_07.inc" END Данная программа подключает несколько внешних файлов: Файл lst_1_02.inc. Файл, содержащий процедуры ввода/вывода общего назначения для работы в цветном текстовом режиме. Файл lst_1_03.inc. Файл мнемонических обозначений кодов управляющих клавиш. Файл lst_1_05.inc. Файл мнемонических обозначений цветов. Файл lst_6_07.inc. Файл, содержащий процедуры для непосредственной работы с контроллером жестких дисков ATA.

Полный листинг программы, выполняющей считывание загрузочного сектора Master-диска канала 1 в режиме DMA. ; Автор текста программы Кулаков Владимир Геннадьевич. IDEAL P386 LOCALS MODEL MEDIUM ; Подключить файл мнемонических обозначений цветов include "lst_1_05.inc" DATASEG ; Текстовые сообщения Txt0 DB LIGHTCYAN,0,17 DB "ТЕСТИРОВАНИЕ РЕЖИМА DMA MASTER-ДИСКА КАНАЛА 1",0 DB YELLOW,5,8,"Содержимое загрузочного сектора " DB "Master-диска канала 1:",0 AnyK DB YELLOW,24,29,"Нажмите любую клавишу",0 ; Сообщения об отсутствии компонентов системы, ; необходимых для запуска примера NoPCI DB LIGHTRED,12,18 DB "Система не поддерживает интерфейс PCI BIOS",0 NoIDEC DB LIGHTRED,12,26 DB "Контроллер PCI IDE не найден",0 BadReg DB LIGHTRED,12,28,"Неверный номер регистра",0 NoHDD DB LIGHTRED,12,21 DB "Master-диск на канале 1 не обнаружен.",0 NoLBA DB LIGHTRED,12,24 DB "Диск не поддерживает режим LBA.",0 ; Сообщения об ошибках при выполнении ; операции считывания DErr1 DB LIGHTRED,12,8,"Тайм-аут: превышена допустимая " DB "длительность выполнения операции.",0 DErr2 DB LIGHTRED,12,25 DB "Неверный код режима адресации.",0 DErr3 DB LIGHTRED,12,27,"Неправильный номер канала.",0 DErr4 DB LIGHTRED,12,27,"Неправильный номер диска.",0 DErr5 DB LIGHTRED,12,26,"Неправильный номер головки.",0 DErr6 DB LIGHTRED,12,17,"Ошибка при выполнении " DB "команды жестким диском.",0 ; Адрес блока регистров контроллера PCI IDE IDEContrRegsBaseAddr DW ? ENDS ; Буфер для работы с диском в режиме DMA SEGMENT DMA_BUF para public 'DATA' DB 8000h DUP(?) ENDS ; Буфер для таблицы PRD SEGMENT PRD_Table para public 'DATA' DB 1024 DUP(?) ENDS SEGMENT sseg para stack 'STACK' DB 400h DUP(?) ENDS CODESEG ;***************************** ;* Основной модуль программы * ;***************************** PROC IDE_DMA_Test mov AX,DGROUP mov DS,AX ; Установить текстовый режим и очистить экран mov AX,3 int 10h ; Скрыть курсор - убрать за нижнюю границу экрана mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Вывести заголовок на экран mov SI,offset Txt0 call ShowColorString call ShowColorString ; Задать номер канала и номер диска mov [ChannelNumber],1 mov [HDDNumber],0 ; Проверить наличие и работоспособность диска call HDD_Presence_Test ; Найти контроллер PCI IDE call SearchBusMasterIDEContr ; Создаем таблицу PRD, состоящую из одной записи mov AX,PRD_Table mov ES,AX ; Вычислить и записать адрес области данных xor EAX,EAX mov AX,DMA_BUF shl EAX,4 mov [ES:0],EAX ; Записать количество передаваемых байтов данных mov [word ptr ES:4],512 ; Установить признак последней строки таблицы mov [word ptr ES:6],8000h ; Загрузить физический адрес таблицы PRD в ; соответствующий регистр контроллера PCI IDE ; Вычислить абсолютный адрес PRDT (умножить ; номер сегмента PRD_Table на 16) xor EAX,EAX mov AX,PRD_Table shl EAX,4 ; Вычислить адрес регистра контроллера mov DX,[IDEContrRegsBaseAddr] add DX,04h ; Записать адрес PRD в регистр out DX,EAX ; Прочитать загрузочный сектор диска в режиме DMA call ReadBootSector ; Окончание работы @@End: ; Ожидать нажатия любой клавиши ; Переустановить текстовый режим и очистить экран mov AX,3 int 10h ; Выход в DOS mov AH,4Ch int 21h ENDP IDE_DMA_Test ;******************************************************* ;* НАЙТИ КОНТРОЛЛЕР PCI IDE И ОТОБРАЗИТЬ НА ЭКРАН * ;* СОДЕРЖИМОЕ РЕГИСТРОВ КОНФИГУРАЦИОННОГО ПРОСТРАНСТВА * ;******************************************************* PROC SearchBusMasterIDEContr near pushad ; Проверить наличие PCI BIOS mov AX,0B101h int 1Ah jc @@PCIBIOSNotFound cmp EDX,20494350h jne @@PCIBIOSNotFound ; Найти контроллер Bus Master IDE по коду класса mov AX,0B103h mov ECX,010180h ;первый вариант кода mov SI,0 int 1Ah jnc @@ReadPCIRegisters ;устройство найдено mov AX,0B103h mov ECX,010185h ;второй вариант кода mov SI,0 int 1Ah jnc @@ReadPCIRegisters ;устройство найдено mov AX,0B103h mov ECX,01018Ah ;третий вариант кода mov SI,0 int 1Ah ; Устройство найдено? jc @@DeviceNotFound ;устройство не найдено ; Устройство обнаружено, его координаты на шине PCI ; находятся в регистре BX @@ReadPCIRegisters: ; Получить базовый адрес блока регистров контроллера IDE mov AX,0B10Ah ;читать двойное слово mov DI,20h ;смещение слова int 1Ah jc @@BadRegisterNumber and CX,0FFF0h ;сбросить младшие 4 разряда mov [IDEContrRegsBaseAddr],CX popad ret ; Обработка ошибок @@BadRegisterNumber: ; Неверный номер регистра mov SI,offset BadReg call FatalError @@DeviceNotFound: ; Не найден контроллер IDE mov SI,offset NoIDEC call FatalError @@PCIBIOSNotFound: ; Не поддерживается PCI BIOS mov SI,offset NoPCI call FatalError ENDP SearchBusMasterIDEContr ;******************************************************* ;* ПРОВЕРИТЬ ПРИСУТСТВИЕ ДИСКА И НАЛИЧИЕ ПОДДЕРЖКИ LBA * ;******************************************************* PROC HDD_Presence_Test near pusha ; Опросить Master-диск канала 1 call ReadHDD_ID ; Диск подключен? cmp [HDDErrorCode],0 jne @@DiskNotFound ; Режим LBA поддерживается? cmp [dword ptr SectorDataBuffer+60*2],0 je @@LBANotSupported popa ret ; Обработка ошибок @@DiskNotFound: ; Диск не найден mov SI,offset NoHDD call FatalError @@LBANotSupported: ; Не поддерживается LBA mov SI,offset NoLBA call FatalError ENDP HDD_Presence_Test ;********************************************* ;* ПРОЧИТАТЬ ЗАГРУЗОЧНЫЙ СЕКТОР В РЕЖИМЕ DMA * ;********************************************* PROC ReadBootSector near pushad ; Сбросить разряды ошибки и прерывания в регистре ; состояния канала 1 mov DX,[IDEContrRegsBaseAddr] add DX,02h mov AL,110b out DX,AL ; Настроить контроллер DMA на запись данных в память ; по каналу 1 ; Загрузить адрес управляющего регистра канала 1 mov DX,[IDEContrRegsBaseAddr] ; Сбросить управляющий регистр mov AL,0 out DX,AL ; Установить бит направления передачи данных mov AL,1000b out DX,AL ; Послать команду чтения сектора 0 (загрузочного) ; Подготовить параметры команды mov [ATAAddressMode],1 ;режим LBA mov [dword ptr SectorAddress],0 ;сектор 0 mov [dword ptr ATASectorNumber],0 mov [ATAFeatures],0 mov [ATASectorCount],1 ;прочесть один сектор mov EAX,[SectorAddress] ; Послать команду диску mov [ATACommand],0C8h ;чтение в режиме DMA call SendCommandToHDD ; Проверить код ошибки cmp [HDDErrorCode],0 ;имелась ошибка? jne @@Error ;обработка ошибки ; Активировать канал 1 контроллера DMA mov DX,[IDEContrRegsBaseAddr] mov AL,1001b out DX,AL ; Ожидать готовность данных HDD mov AX,0 mov ES,AX mov DX,[HDDBasePortAddr] add DX,7 ;адрес регистра состояния @@WaitCompleet: ; Проверить время выполнения команды mov EAX,[ES:046Ch] sub EAX,[HDDTime] cmp EAX,MaxHDDWaitTime ja @@Err1 ;ошибка тайм-аута ; Проверить готовность in AL,DX test AL,88h ;состояние сигнала BSY и DRQ jnz @@WaitCompleet ; Ожидать конца цикла DMA mov DX,[IDEContrRegsBaseAddr] add DX,02h @@WaitDMAOperationEnd: in AL,DX test AL,1 jnz @@WaitDMAOperationEnd ; Сбросить управляющий регистр канала 1 контроллера DMA mov DX,[IDEContrRegsBaseAddr] mov AL,0 out DX,AL ; Отобразить на экран содержимое прочитанного сектора ; в ASCII-кодах push DS mov AX,DMA_BUF mov DS,AX mov AX,0B800h mov ES,AX mov DI,7*160+8*2 xor SI,SI ; Задать светло-голубой цвет и синий фон mov AH,LIGHTCYAN+BLUE*16 ; Цикл по строкам mov DX,8 ;счетчик строк @@OutNextString: ; Цикл по символам строки mov CX,64 ;счетчик символов в строке @@OutNextChar: lodsb stosw loop @@OutNextChar add DI,16*2 dec DX jnz @@OutNextString pop DS ; Ожидать нажатия любой клавиши и выйти из процедуры mov SI,offset AnyK call ShowColorString call GetChar popad ret ; Обработка ошибок @@Error: cmp [HDDErrorCode],1 je @@Err1 cmp [HDDErrorCode],2 je @@Err2 cmp [HDDErrorCode],3 je @@Err3 cmp [HDDErrorCode],4 je @@Err4 cmp [HDDErrorCode],5 je @@Err5 cmp [HDDErrorCode],6 je @@Err6 @@Err1: mov SI,offset DErr1 call FatalError @@Err2: mov SI,offset DErr2 call FatalError @@Err3: mov SI,offset DErr3 call FatalError @@Err4: mov SI,offset DErr4 call FatalError @@Err5: mov SI,offset DErr5 call FatalError @@Err6: mov SI,offset DErr6 call FatalError ENDP ReadBootSector ;***************************************************** ;* ФАТАЛЬНАЯ ОШИБКА * ;* ВЫДАТЬ СООБЩЕНИЕ И ВЫЙТИ ИЗ ПРОГРАММЫ * ;* Параметры: * ;* DS:SI - указатель на "цветную" строку сообщения * ; об ошибке (в формате для ShowColorString).* ;***************************************************** PROC FatalError near ; Вывести сообщение об ошибке call ClearScreen call ShowColorString mov SI,offset AnyK call ShowColorString call GetChar ; Аварийный выход mov AH,4Ch int 21h ENDP FatalError ENDS ; Подключить процедуры вывода данных на экран include "lst_1_02.inc" ; Подключить процедуру непосредственного считывания ; сектора с жесткого диска include "lst_6_07.inc" END Данная программа подключает несколько внешних файлов: Файл lst_1_02.inc. Файл, содержащий процедуры ввода/вывода общего назначения для работы в цветном текстовом режиме. Файл lst_1_03.inc. Файл мнемонических обозначений кодов управляющих клавиш. Файл lst_1_05.inc. Файл мнемонических обозначений цветов. Файл lst_6_07.inc. Файл, содержащий процедуры для непосредственной работы с контроллером жестких дисков ATA.

Полный листинг резидентной программы защиты жесткого диска от записи. После первого запуска программа запрещает запись на жесткий диск, а после повторного - разрешает. Выгрузка данной программы из памяти не предусмотрена. Программа корректно работает только в режиме эмуляции Ms-DOS. Запускной файл в формате .com . ;===================================================== ; скопировано из PC MAGAZINE v6 n2 1987 ;===================================================== cseg segment assume cs:cseg org 100h ; пропуск для прогр сегм преф ; start: jmp initialize ; переход на установку ; oldint13 dd ? ; адрес старого 13 прер - работа с диском switch db 0fh ; защита есть/нет ; newint13 proc far cmp ah,03h ; запись на диск ? je checkstat ; да - проверить можно ли ; cmp ah,05h ; форматирование диска ? je checkstat ; да - проверим можно ли ; continue: jmp cs:[oldint13] ; можно выполнить операцию ; checkstat: cmp switch,00h ; если защита включена jne continue ; eсли выполнять не надо cmp dl,00h ; был выбран флоп A:? je continue ; eсли да - выполнять cmp dl,01h ; был выбран флоп B: ? je continue ; да - выполнить abort: mov ah,03h ; установить код ошибки защита записи stc ; установить статус "была ошибка" ret 2 ; возврат с флагом выхода ; newint13 endp ; конец нового обработчика прерывания ; ; установка программы в память резидентно ; начинаем поиском существующей копии кодов ;--------------------------------------------- initialize: mov dx,offset newint13 ; смещение начала искомых кодов mov ax,cs ; ds:si указывает на цель mov es,ax ; es:di указывает на источник ; nextseg: dec ax ; ищем предыдущий сегмент mov ds,ax ; загружаем новый сегмент для поиска mov si,dx ; указатель на начало строки mov di,dx ; указатель на начало строки ; 4 слова должны соответствовать, чтобы подтветдить существование программы ; т.е. программа уже загружена в память mov cx,0004h ; 4 слова должны соответствовать cld ; чистим флаг автоприращения в df repe cmpsw jne notfound ; не соответствует - продолжаем попытки ; локальная копия программы может находиться во вводном буфере ; всякая локальная копия может быть идентифицирована по switch уст в 0fh cmp ds:switch,0fh ; это ранее установленная программа? jne togglesw ; да - отметить switch notfound: cmp ax,0001h ; прекратить поиск в нижней памяти jne nextseg ; ; если мы вышли из цикла не найдя кодов - надо проинсталлировать программу ; mov switch,00h ; включить switch - проинсталлирована mov ax,3513h ; установить для получения старого вектора int 21h ; обращение к dos ; ; сохранить старый вектор в памяти ; mov word ptr cs:[oldint13],bx mov word ptr cs:[oldint13+2],es ; push cs pop ds ; установить ds = cs ; послать сообщение , завершиться и остаться в памяти mov dx,offset protect_on mov ah,09h ; код функции печати строки int 21h ; ; установить в вектор прерываний адрес новой программы mov dx,offset newint13 mov ax,2513h ; установить новый адрес обработчика int 13 int 21h ; выполнить ; mov dx,offset initialize ; столько байтов оставить int 27h ; завершить и остаться в памяти ; ; если программы уже сидят в памяти - надо только переустановить switch togglesw : not ds:switch ; ds - установлена на поиск cmp ds:switch,00h ; переключатель установлен ? je on mov dx,offset protect_off jmp exit on: mov dx,offset protect_on exit: mov ah,09h ; печать строки push cs pop ds ; переустановка ds int 21h int 20h ; возврат в дос protect_on db "Write on hard disk restricted.$" protect_off db "Write on hard disk available.$" cseg ends end start

Соседние файлы в папке Учебник