Реферат: Низкоуровневое программирование для Дzenствующих
Низкоуровневое программирование для Дzenствующих #Бредисловие Последняя ночь перед...Как таинственная и трагична последняя ночь перед страшным экзаменом. Там не дадут достать или поднять маленький обрывок бумаги, на кончике котором зашифрована, напечатана или отксеренна судьба грешной души студента. Спасения нет, шары НЕ БУДЕТ!!! Но остаётся только одна единственная ночь, чтобы изменить мир...
Сквозь тусклый свет призраки спускаются к бедной голове, что, склонившись над таинственной тетрадью, словно заклинание, повторяет непонятные слова из 21-ой буквы, в которых заключено имя страшного предмета.
Часовая стрелка незаметно скользит вперёд. Вот-вот и она уже на 12.00. Текст расползается перед глазами, духи говорят с тобою. Мистика. В чёрной чашке с надписью NestCafe бурлит чёрная жидкость. Кошмарные видение ненаступившего «завтра» висят в воздухе комнаты. Всё соединяется в ужасный единый крик: «Завтра не наступит»… а потом слышится звон… тяжёлый звон из реальности, звон будильника…. Наступило последнее утро.
Мистика, неправад ли? WASM.RU спешит поздравить всех Дzenствующих студентов с окончанием кошмаров по имени "сессия". А всем поступающим желает познать её таинство.
И вот теперь, когда наступило лето, (а у кого-то может быть идёт практика, или сборы на военной кафедре), когда душа поёт и ликует, самое время занятся безумством. Тем более, если это замечательно безумство программирование на ASSEMBLERе.
Как утверждает сам Serrgio[HI-TECH], программирование на ассемблере не только делает ум гибким и лёгким, а так же повышает кислотно-щелочной баланс, выводит шлаки, позволяет закодировать от курения, выпивания и других забавных занятий, а кроме того, улучшает внутренний и внешний товаробмен веществ. А самое главное увеличивает мужскую силу и женское обаяние (я ничего не забыл? Если да присылайте свои объявления по адресу dzenreclama@kanal.ort).
И вот, чтобы хорошо расслабится, я предлагаю, заняться ещё более безумным делом чем программирование на ассемблере. Вы наверное удивитесь: "А что такое возможно?". О, да!!! Такое возможно. Читайте далее.
^ Рустам Галиев Нестандартный загрузчик (часть 1)
Начальная загрузка
Загрузочный код
Данная статья предназначена для тех, кто хочет подробнее узнать о процессе начальной загрузки компьютера и поэкспериментировать с ним. Материал излагается с использованием языка ассемблера, однако каждый шаг подробно комментируется и разобраться в нем при желании смогут и читатели, не имеющие специальной подготовки (хотя знакомство с ассемблером и архитектурой процессора Intel 0х86 облегчит восприятие). Не потребуется также никакого специального программного обеспечения: все описываемые действия проделываются с использованием отладчика debug, входящего в состав Windows 95/98. Проделав описанные в статье действия на своем компьютере, вы сможете создать вспомогательную программу wb.com и установить в реестре ее ассоциацию с расширением файлов .bot, что позволит одним щелчком мыши переносить созданные с помощью debug файлы на дискету, сделав ее загружаемой.
^ Начальная загрузка
После проверки программой BIOS подключенного оборудования управление передается процедуре начальной загрузки с дисков, доступ к которой можно получить через прерывание INT 19h. Данная процедура загружает всего один сектор (первый) с нулевой дорожки нулевой головки, размещая его в памяти по адресу 7С00h, и передавая управление после загрузки сектора по этому же адресу. В области данных BIOS хранится последовательность обращения к дискам, пока не будет произведена успешная загрузка (это значение устанавливается через BIOS Setup). Ответственность за дальнейшую загрузку компьютера ложится на код, содержащийся в загрузочном секторе соответствующего диска.
Совершенно очевидно, что из-за ограниченного объема сектора (512 байт) загрузочный код разнообразием не блещет и в основном сводится к операции загрузки с диска в оперативную память дополнительных секторов, содержащих ядро операционной системы, и передаче управления по соответствующему адресу памяти. Кроме кода загрузки, в загрузочном секторе содержится также приведенный ниже в таблице блок параметров BIOS с данными о форматировании диска.
Смещение
Размер, байт
Содержание
3h
8
Аббревиатура и номер версии ОС
Bh
2
Число байтов в секторе (512)
Dh
1
Число секторов в кластере
Eh
2
Число резервных секторов в резервной области раздела
10h
1
Число копий FAT в разделе (2)
11h
2
Количество 32-байтных дескрипторов файлов в корневом каталоге
13h
2
Общее число секторов в разделе
15h
1
Тип носителя информации (для современных дискет F0h)
16h
2
Количество секторов, занимаемых одной копией FAT
18h
2
Число секторов на дорожке
1Ah
2
Число головок
1Ch
4
Число скрытых секторов перед началом раздела (для дискет 0)
20h
4
0 (используется FAT32)
24h
1
Номер дисковода (для дискет - от 0 до 3)
25h
1
0 (для Windows NT)
26h
1
Признак расширенной загрузочной записи (29h)
27h
4
Номер логического диска (создается при форматировании)
2Bh
11
Метка диска (текстовая строка)
36h
8
Аббревиатура типа файловой системы
3Eh
Начало загрузочного кода
Первые три байта загрузочного сектора содержат инструкцию безусловного перехода (^ JMP) на код, начинающийся после блока параметров BIOS. Кроме того, последними двумя байтами являются 55h и AAh (сигнатура – признак загрузочного сектора логического диска). Желающие могут посмотреть на эти данные, воспользовавшись программой diskedit.exe из пакета Norton Utilities, и прочитать с ее помощью физический сектор №1 любой форматированной дискеты. Данные блока параметров BIOS должны присутствовать всегда, поскольку Загрузчик BIOS проверяет его целостность.
^ 2.Загрузочный код
Приступим к созданию нашего загрузчика. Первым делом надо загрузить весь код с дискеты в оперативную память, затем передать ему управление. При этом необходимо учесть, что мы не можем воспользоваться услугами операционной системы – можно использовать лишь низкоуровневые функции BIOS. Для работы с дисками существуют функции прерывания INT 13h, при вызове которых используются следующие регистры:
^ AH – функция (0 – сброс, 2 – чтение сектора, 3 – запись сектора);
AL – число секторов (для чтения или записи);
BX – буфер памяти для ввода-вывода данных (в паре ES:BX);
^ CH – номер дорожки;
CL – номер начального сектора;
DH – номер головки (для дискет – 0 или 1);
DL – номер дисковода (0=А, 1=B).
В случае успешного завершения функции флаг переноса (CF) сбрасывается; при ошибке он установлен.
Работа с дисководом для гибких дисков имеет свои особенности; это довольно медленное устройство, дискеты можно вынимать, поэтому ошибки случаются сравнительно часто (например, при обращении к дисководу мотор не успевает “разогнаться”), поэтому операции чтения или записи при ошибках обычно повторяют по 3 раза, и лишь после трех последовательных неудач выдают сообщение об ошибке конечному пользователю.
Для наших целей мы используем простую линейную модель; это означает, что весь код у нас будет записан последовательно за загрузочным сектором: сектора 2–18 нулевой дорожки со стороны нулевой головки (в предположении, что используется стандартная дискета на 1,44 Мб), затем сектора 1–18 нулевой дорожки со стороны первой головки; далее переходим на первую дорожку со стороны нулевой головки и т.д. Считывание, естественно, должно производиться в том же порядке. При этом необходимо где-то записать количество секторов, которые необходимо таким образом считать; сохраним это значение в двух байтах после блока параметров BIOS (со смещением 3Eh). Не забудьте, что загрузочный сектор размещается в памяти, начиная с адреса 7C00; это значит, что в памяти число секторов, которые необходимо прочитать с дискеты, будет находиться по адресу 7C3E, а с адреса 7C40 будет код. По адресу же 7C00 должна находится команда безусловного перехода
JMP 7C40
Для последовательного чтения секторов организуем цикл, после каждой итерации значение по адресу 7C3E будем уменьшать на 1, пока оно не достигнет 0 (это и будет сигналом выхода из цикла). Необходимо также предусмотреть сообщение об ошибке на случай трех последовательных безуспешных попыток чтения сектора; для этой цели используем незамысловатый текст “Read error” (необходимо помнить, что при начальной загрузке кодовая таблица с кириллицей в видеопамять не загружена, поэтому для сообщений нельзя использовать русский шрифт).
Итак, по адресу 7C40 размещается следующий код (все числа в коде – шестнадцатеричные):
MOV AL,1 ; считать 1 сектор
MOV BX,7E00 ; разместить в памяти, начиная с адреса 7E00, т.е.
; следующие 512 (200h) байт после 7C00
XOR CH,CH ; обнуляем CH – дорожка 0
MOV CL,2 ; сектор 2 (1-й сектор уже считан)
XOR DX,DX ; обнуляем DX: DH=0 (головка 0), DL=0 (дисковод 0,
; т.е. А: )
Начальная инициализация произведена. Далее начинается цикл, в котором читается сектор (до трех попыток при ошибке). После успешного считывания данных номер сектора (AL) увеличивается на 1, и если он превысил значение 18, устанавливается равным 1, а номер головки (DH) увеличивается на 1. Аналогично номеру сектора, если номер головки превысит 1, устанавливается 0, и увеличивается номер дорожки (CH). Номер дорожки должен находиться в пределах 0–79, т.е. не должен достигать 80 (50h); если это произошло, выдается сообщение об ошибке. Значение счетчика считываемых секторов (по адресу 7C3E) уменьшается на 1, и если оно еще не достигло 0, цикл повторяется:
LOOP:
MOV SI,3 ; 3 попытки повторного чтения
REPEAT:
MOV AH,2 ; функция 2 (чтение сектора)
INT 13 ; вызов прерывания BIOS 13h
JNC OK ; если ошибки не было, продолжить с OK
; Попадание сюда означает, что была ошибка чтения
DEC SI ; уменьшим число повторов на 1
JZ ERROR ; если число повторов =0, т.е. 3 безуспешные
; попытки, выход по ошибке
XOR AH,AH ; обнуляем AH - функция 0 (сброс)
INT 13 ; сброс дисковода для повторной попытки
JMP REPEAT ; повтор попытки чтения
OK: ; Сюда попадаем, если не было ошибки чтения
INC CL ; следующий сектор
CMP CL,12 ; проверяем, достигло ли число секторов 18 (12h)
JNG NEXT ; если не превысило, дальше с NEXT
; (Число секторов превысило 18):
MOV CL,1 ; установить сектор 1
INC DH ; увеличить номер головки на 1
CMP DH,1 ; проверяем, достиг ли номер головки 1
JNG NEXT ; если не превысило, дальше с NEXT
; (Номер головки превысил 1):
XOR DH,DH ; обнуляем DH: головка 0
INC CH ; увеличить номер дорожки
CMP CH,50 ; проверяем, достигнута ли дорожка 80 (50h)
JGE ERROR ; если достигнута - ошибка
NEXT:
DEC WORD PTR [7C3E] ; уменьшить счетчик читаемых
; секторов (по адресу 7C3E) на 1
JZ END ; если достигнут 0 - загрузка окончена,
; дальше перейти к END
; Сюда попадаем, если прочитаны не все сектора
ADD BX,200 ; следующий сектор разместить в памяти со
; смещением 512 (200h) байт относительно
; начала настоящего, т.е. непосредственно
; после него
JMP LOOP ; перейти в начало цикла (новая итерация)
END:
JMP 7E00 ; все сектора прочитаны: управление
; передается по адресу загрузки второго
; сектора (непосредственно после загрузочного)
Осталось только реализовать вывод сообщения об ошибке. Для этого воспользуемся функцией ^ 13h прерывания BIOS 10h. Данная функция выводит символьную строку. В регистрах должны быть следующие значения:
AH – функция (13h);
AL – один из 4 возможных сервисов
(мы используем 3 – вывод символа с атрибутом и перевод курсора);
BH – страница видеопамяти (обычно 0);
BP – адрес выводимой строки (в паре ES:BP);
CX – длина строки (в символах);
DX – координаты на экране (DH – строка, DL – столбец).
Итак, ошибку обрабатывает следующий код:
ERROR:
MOV AH,13 ; функция вывода строки
MOV AL,3 ; сервис 3
MOV BH,0 ; страница 0 (по умолчанию)
MOV BP,(TEXT) ; адрес выводимой строки
MOV CX,0C ; вывести 12 (0Ch) символов
XOR DX,DX ; координаты (0,0)
INT 10 ; вызов прерывания BIOS 10h
После вывода текста необходимо приостановить выполнение программы до того момента, пока пользователь не прочтет сообщение и явным образом не даст сигнал, что можно продолжать дальше. Обычно для этого используют запрос на ввод данных с клавиатуры через прерывание BIOS 16h. Выполнение программы при этом приостанавливается до тех пор, пока не будет нажата какая-нибудь клавиша на клавиатуре. Итак:
XOR AX,AX ; устанавливаем AX=0 (функция ввода с клавиатуры)
INT 16 ; вызов BIOS
Программа завершилась, что дальше? Обычно в этом месте ставят команду возврата в операционную систему. Однако, в нашем случае это не имеет смысла – операционная система не загружена. Поэтому просто поставим команду перезагрузки системы:
INT 19
Если дискета оставлена в дисководе, наша программа загрузится, и будет выполнена снова; если ее вытащить, загрузится обычная ОС (DOS или Windows).
Пора приступить к вводу и ассемблированию программы; для этого, как я уже говорил, используем отладчик debug. Однако сначала нужно вместо текстовых меток расставить действительные значения адресов памяти, а сделать это можно только с помощью “двух проходов”. При первом проходе вместо реальных значений адресов подставляются произвольные числа; необходимо только следить, чтобы они отличались от настоящих адресов не слишком радикально (особенно в случаях команд ближних условных переходов: их можно использовать лишь при переходах в пределах ?128 байт). Составляем таблицу, в которую вписываем все метки, встречающиеся в нашей программе; по мере набора программы и “прохождения” соответствующих меток проставляем в таблице рядом с каждой меткой ее действительный адрес. Затем повторно вводим все те команды, которые содержали метки, уже с реальными значениями адресов.
В случае с “реальным” ассемблером всей этой канителью занимается компилятор. В нашем случае, поскольку вся эта работа была уже проделана автором, вы можете просто воспользоваться уже готовыми адресами, поверив мне на слово, что это действительно те самые адреса, которые нужны. Итак, начинаем работать. Щелкните на кнопке “Start” (“Старт”) и выберите пункт “Run” (“Выполнить”). Наберите в командной строке debug. Откроется окно сеанса DOS с черточкой – приглашением отладчика debug. Программа должна начинаться у нас с адреса 7C00, поэтому набираем:
a 7C00
В ответ появится что-то вроде
200E:7C00
Эти числа означают адрес вводимой команды в виде сегмент:смещение. Адрес сегмента в вашем случае будет другим, но это не играет роли. Внимание обращать следует лишь на смещение. Вводим нашу первую команду:
JMP 7C40
После ввода каждой команды нажимаем ; в ответ debug выдаст адрес следующей вводимой команды. В нашем случае, после первой команды следует область блока параметров BIOS, которую следует пропустить. Для этого еще раз нажимаем , затем, чтобы перейти к вводу команд с адреса 7C40, набираем:
а 7C40
Вот листинг оставшейся части программы (все команды мы уже разбирали; учтите, что некоторые одинаковые команды могут обозначаться по-разному, например, JNC и JNB, JNG и JLE и др., так что здесь нет ошибки):
200E:7C40 MOV AL,01
200E:7C42 MOV BX,7E00
200E:7C45 XOR CH,CH
200E:7C47 MOV CL,02
200E:7C49 XOR DX,DX
200E:7C4B MOV SI,0003
200E:7C4E MOV AH,02
200E:7C50 INT 13
200E:7C52 JNB 7C5D
200E:7C54 DEC SI
200E:7C55 JZ 7C85
200E:7C57 XOR AH,AH
200E:7C59 INT 13
200E:7C5B JMP 7C4E
200E:7C5D INC CL
200E:7C5F CMP CL,12
200E:7C62 JLE 7C76
200E:7C64 MOV CL,01
200E:7C66 INC DH
200E:7C68 CMP DH,01
200E:7C6B JLE 7C76
200E:7C6D XOR DH,DH
200E:7C6F INC CH
200E:7C71 CMP CH,50
200E:7C74 JGE 7C85
200E:7C76 DEC WORD PTR [7C3E]
200E:7C7A JZ 7C82
200E:7C7C ADD BX,0200
200E:7C80 JMP 7C4B
200E:7C82 JMP 7E00
200E:7C85 MOV AH,13
200E:7C87 MOV AL,03
200E:7C89 MOV BH,00
200E:7C8B MOV
BP,7C9B
200E:7C8E MOV CX,000D
200E:7C91 XOR DX,DX
200E:7C93 INT 10
200E:7C95 XOR AX,AX
200E:7C97 INT 16
200E:7C99 INT 19
200E:7C9B
По адресу 7C9B у нас должен находиться текст “Read error”, который (в коде ASCII с добавленными байтами-атрибутами) вводится следующим образом:
200E:7C9B DW 752,765,761,764,720,765,772,772,76F,772
200E:7CAF
Наконец, в последних двух байтах первого сектора должна быть сигнатура. Нажимаем еще раз , затем вводим:
a 7CFE
200E:7CFE DB 55,AA
200E:7E00
Строго говоря, это еще не вся программа. Если вы вспомните, после загрузки всех секторов управление передается по адресу 7E00, а у нас по этому адресу ничего нет, да и никаких других секторов тоже нет. Тем не менее, мы можем сохранить этот кусок и использовать его в виде шаблона при создании других программ. В этом случае все, что нам потребуется, – это добавить код, начиная с адреса 7E00 – и независимо от того, сколько места он будет занимать, при записи на дискету наша программа сможет без всякой посторонней помощи сама себя загрузить и выполнить.
Сначала надо дать нашему шаблону имя, скажем, “template.bot”. О расширении .bot немного позже, сейчас же присвоим это имя:
n template.bot
И сохраним его; для этого сначала надо в регистр CX внести размер сохраняемой программы. Размер определяется вычитанием из последнего смещения, полученного нами при вводе программы, числа 100 (не забудьте, что все числа – шестнадцатеричные). В нашем случае это будет 7D00:
r cx
Выводится текущее значение регистра CX и двоеточие для ввода нового значения. Вводим:
7D00
Теперь записываем:
w
После успешной записи на экран будет выведено: Writing 7D00 bytes
Шаблон готов. Попробуем создать с его помощью простейшую тестовую программу. Скопируем файл шаблона под другим именем, например, “test.bot”. Теперь откроем этот файл в отладчике debug. Это удобно сделать следующим образом. В файловом менеджере DOS (например, FAR или Norton Commander) перейдите в каталог, в котором вы сохранили файл “test.bot”. В командной строке наберите:
debug test.bot
Теперь по адресу 7E00 (набрав ‘a 7E00’) к этой программе можно добавить дополнительный код, например, такой:
200D:7E00 MOV AH,13
200D:7E02 MOV AL,3
200D:7E04 XOR BH,BH
200D:7E06 MOV BP,7E17
200D:7E09 MOV CX,9
200D:7E0C XOR DX,DX
200D:7E0E INT 10
200D:7E10 XOR AX,AX
200D:7E12 INT 16
200D:7E14 JMP 8000
200D:7E17 DW 753,765,763,774,76F,772,720,732,720
200D:7E29
Этот код аналогичен коду, выводящему сообщение об ошибке на экран. В данном случае выводится сообщение “Sector 2”; управление передается по адресу 8000h. Ценность этого небольшого фрагмента кода в том, что его можно с небольшой модификацией разместить в различных секторах и сделать так, чтобы он выводил на экран номер сектора, в котором данный код находится. Это позволяет проконтролировать, что сектора загружаются, и передают друг другу управление нормально. Так, в третьем секторе (по адресу 8000) можно набрать этот же код, только по адресу 8006 на этот раз должна быть команда ‘MOV BP, 8017’ (т.е. необходимо соответственно увеличивать этот адрес на 200h). По адресу 8014 можно вставить команду ‘INT 19’, чтобы завершить программу; если же нужно задействовать еще один сектор, надо просто передать ему управление, например, ‘JMP 8200’, и т.д. В области данных необходимо также произвести изменения в соответствии с номером сектора: в третьем секторе предпоследнее число (732) должно быть 733, в четвертом – 734 и т.д. Для 10 сектора меняются уже два последних числа – ‘731,730’ (что соответствует символам ‘1’ и ‘0’). Не забудьте после добавления кода сохранить программу, предварительно записав в регистр CX ее новый размер (по последнему смещению минус 100).
Программа готова, но запустить ее в таком виде нам не удастся. Начало нашей программы должно быть записано в загрузочном секторе, причем так, чтобы сохранить блок параметров BIOS. Дело не только в том, что штатными средствами операционной системы этого сделать нельзя; дело еще и в том, что с помощью отладчика debug можно ассемблировать и сохранять небольшие исполняемые файлы, но они будут в формате COM. Формат COM предполагает, что начало файла соответствует смещению 100h, и debug записывает программу на диск соответствующим образом. Поскольку наш загрузчик (как и вообще любой загрузчик) размещается в памяти, начиная с адреса 7С00, debug сохранит в нашем bot-файле перед началом собственно программы 7B00h байт “мусора”. Поэтому придется создать вспомогательную программу wb.com (от “Write Boot”), чтобы сохраненный нами файл в “формате” .bot адекватным образом переписать на дискету.
(продолжение следует...)
#Послесловие
Иногда я задаюсь вопросом, кто круче ^ Бог или студент, и тогда понимаю, что Бог творил мир 6 дней, и лишь на седьмой отдыхал. А студент отдыхает пол года, а творит мир за одну ночь...
До следующего выпуска, в котором мы будем создавать мир.
C уважением, Edmond/HI-TECH.
^ Низкоуровневое программирование для Дzenствующих #34 ########################################################################### #Бредисловие Сорванные башни
(часть 1)
- У нас сегодня будет заголовок или нет?
- Будет, - сказал Дрозд. - Я уже букву "К" нарисовал.
- Какую "К"? При чем здесь "К"?
- А что, не надо было?
- Я сейчас умру, - сказал Роман. - Газета называется "За передовую магию". Покажи мне там хоть одну букву "К"!
А. и Б. Стругацкие, "Понедельник..."
^ #Бредисловие от WASM GROUP (тайный архив переписки дzenствующих, полученный ХАКЕРОМ Саней за ЧАШКОЙ ПиВа)
<00E>: Ну что, рассылку делаем?
Надо вступление написать, оформить художественно и с чувством.
Про сессию что-нибудь...
<00F>: Сейчас займусь... Какой-то бред в голову лезет... 8-)))
<00E>: А ну покажь!... Хе... хе-хе-хе... Что, плющит тебя, Федор Михайлович? ;)
<00F>: Да, конкретно башню рвет... :))
<00C>: Забей, Сеня! (с) "Братва и кольцо"
<00E>: Ок, пускаю в рассылку!
<00A>: Да сразу - на сайт! :)
<00F>: ??? :-О А теперь у кого башню рвет? ХАХА!!! ЭТО - в рассылку???
<00E>: Аль у тебя что-то лучше есть для оформления?
<00F>: Мда... пока нет :( Но там много получается...
<00E>: Погоди! Зачем оформление? Сделаем сериал ;)
"Телекомпания WASM GROUP & HI-TECH GROUP презент.". Сценарий твой,
PROдюсер 00A, а я на белом окне (или коне?).
Надеюсь по сценарию главный герой красивый, умный и так далее? :))
<00F>: Не первое, и не второе, а про "так далее" точно не знаю.
<00A>: У нас сегодня будет рассылка или где?
<00E>: Или гдеееее :)))
<00F>: On my way, красный лидер!
<00E>: ;) Affirmative! Loading Dreamweaver.exe!
[Progressssssssssss50%____________]
^ Гарри Поттер и девайс маглов
Получив список учебников на следующий год, Гарри был удивлен. Среди "Основ магии слова" и пособия по выращиванию королевских виверн в домашних условиях были такие книги как "Современное программное обеспечение", "Секреты системного реестра" и "Вижуал Бейсик для начинающих". Ну это еще куда ни шло, но что такое "Windows для чайников" или "Основы вирусной атаки"?
В лавке магических книг эти лежали в сторонке и магическими не выглядели совершенно. Да, самые обычные магловские книги!
- А, Поттер, великий ламер, книжечки покупаешь? - раздался за спиной голос, по которому Гарри безошибочно узнал Драко Малфроя. Гарри обернулся. Да, это был Малфрой, с новенькой тележкой-самокатом, на которой лежали, кроме всех прочих учебников, яркие журналы с непонятным названием "Xakep" и книга, на обложке которой Гарри разглядел надпись "Internet". Пока Гарри подбирал слова, чтобы ответить на непонятное оскорбление (а в оскорбительности странного эпитета сомневаться не приходилось), Малфрой продолжил:
- Да, Поттер, это тебе не в квиддиш играть. Тут мозги нужны, интеллект!
- Тогда тебе-то точно ничего не светит, - отрезал Гарри и вышел из лавки под язвительный голос Малфроя:
- Посмотрим, как тебе понравятся нюки и войдозер, Поттер!
...Все выяснилось в первый учебный день. Новый предмет назывался магловедение и вел его декан Слизерина Северус Снегг. "А при чем здесь все эти windows?"- шепотом спросил Гарри у Рона.
- Минус 50 баллов Гриффиндорфу! - раздался над самым ухом голос Снегга. - Я требую внимания и не потерплю небрежного отношения к своему предмету!
Снегг прошелся по притихшему классу и откашлялся.
- Итак, мы будем изучать технику маглов. Одним из основных девайсов (то есть устройств) является электронно-вычислительная машина, или просто - компьютер. Я расскажу вам, как с его помощью можно рассчитать что угодно - даже силу действия заклинаний и зелий - за считанные доли секунды. Вы узнаете, как получить моментальное сообщение из любого города мира и как его отправить. Программистов из вас наверняка не выйдет, но пользователями вы станете и даже освоите Visual Basic. Мне эта тема близка как специалисту по защите от темных сил. Один из наших великих волшебников доказал, что в мире маглов именно компьютер является такой силой - а врага надо знать в лицо. Его работы, кстати, публиковались и у маглов - вы, Грейнджер, могли их видеть.
Тишину нарушило хихиканье Малфроя. Снегг даже бровью не повел. Рон не сдержался:
- Почему вы не делаете замечания Малфрою?
- Минус 100 баллов Гриффиндорфу! - Взревел професор Снегг. - Разговаривать, Уизли, будете, когда я вас спрошу! ...Итак, продолжим. При работе с компьютером вас подстерегает множество опасностей, одна из которых - вирусы. Это такие же программы, однако их назначение - наносить разрушения компьютерной системе. Это что-то похожее на заклинания, внесенные в список запрещенных. Программы пишут программисты. Знаете, откуда берутся программисты? Это волшебники, родившиеся в семьях обычных маглов, и не подозревающие о своих способностях. Если их матери пили пиво во время беременности, программисты рождаются Темными. Именно они и пишут вирусы. И не думайте, что предмет просто зачетный! Я договорился с ректором, и мой экзамен будет среди обязательных, когда вы будете сдавать летнюю сессию - вашу последнюю сессию в Хогвартсе. Кстати, сессия будет в конце лета - учебный план этого курса объемист, а это ваш последний год обучения и отдохнуть вы успеете. А кое-кто наотдыхается вволю. На экзамене я заражу вирусами ваши компьютеры и без колебаний отчислю любого, кто не справится! Это и вас касается, Поттер! Поттер!
Гарри, засмотревшийся на профиль Гермионы, вздрогнул.
- Может быть, я сказал, что можно ловить ворон, Поттер? Минус 50 баллов Гриффиндорфу! Или вы все знаете? Ну-ка, скажите мне, как протекает процесс загрузки?
Гарри молчал. Руку подняла, как всегда, Гермиона. На каникулах она приобрела с рук Pentium II и уже успела побродить по интернету. Знание всех языков без словаря весьма помогало. На одном из русских сайтов она видела статью, где рассказывалось о написании "Нестандартного Загрузчика", и хотя мало что поняла, в общих чертах знала. Особенно её поразило содержание второй части этой статьи, которую она запомнила особенно хорошо.
^ Рустам Галеев 00e>00f>00e>00a>00f>00e>00f>00e>00f>00a>00e>00c>00f>00e>00f>00e>^ Нестандартный загрузчик (часть 2)
Вспомогательная программа
Изменения в реестре
3. Вспомогательная программа
Алгоритм действий следующий. При запуске программы wb.com ей в командной строке в качестве параметра передается название bot-файла, который необходимо скопировать на дискету. Далее открываем этот файл с использованием функции 3Dh прерывания DOS 21h, и сохраняем в памяти дескриптор открытого файла. Файловый указатель перемещаем в позицию 7B00h (пропуская “мусор” в начале файла). Считываем первые 512 байт (будущий загрузочный сектор), и сохраняем его в отдельном буфере, поскольку, во-первых, нам надо будет добавить туда реальный блок параметров BIOS, считанный из загрузочного сектора дискеты, а во-вторых, по смещению 3E (непосредственно после блока параметров) нам необходимо поместить число записанных на дискету секторов (после их успешной записи). Для этой цели загрузочный сектор дискеты также считываем и сохраняем в отдельном буфере; данные блока параметров BIOS (смещения с 3h по 3Eh) копируем из второго буфера в первый. Далее организуем цикл:
считываем 512 байт из открытого нами bot-файла в третий буфер;
записываем данные из этого буфера в соответствующий сектор дискеты;
увеличиваем значение счетчика секторов по смещению 3Eh в первом буфере;
когда при очередной итерации будет прочитано 0 байт (конец файла), запишем данные из первого буфера (с окончательным значением счетчика записанных секторов) в загрузочный (первый) сектор дискеты.
Обработка ошибок в программе сведена к минимуму, но при использовании файловых операций совсем обойтись без вывода сообщений невозможно. Первым делом в начале работы программы выводится сообщение: “Вставьте в дисковод А: чистую дискету и нажмите любую клавишу”. Поскольку вывод осуществляется посредством функции 40h прерывания DOS 21h, можно использовать русские буквы, а также символы перевода строки, возврата каретки, табуляции и т.д. Второе сообщение выводится при ошибке открытия файла (например, если неправильно указано имя файла): “Ошибка открытия файла”. Сообщение “Ошибка чтения дискеты” используется для экономии сразу в двух случаях: при ошибке чтения bot-файла выводится лишь часть сообщения (“Ошибка чтения”), при ошибке чтения с гибкого диска – все сообщение. Последнее сообщение – “Ошибка записи” – для случая безуспешной попытки записи сектора на дискету. В области данных отводятся также три буфера по 512 байт для операций чтения-записи, о которых говорилось выше. И, наконец, два байта отводятся для сохранения дескриптора открытого файла.
Приступим к написанию кода. Область данных расположим в начале файла, поэтому первой командой будет безусловный переход для обхода этих данных:
^ JMP INVITE
Условно обозначим наши данные следующими метками (впоследствии при вводе с помощью debug подставим вместо них реальные адреса; пока же вместо адреса будем ставить соответствующую метку в скобках): выводимые сообщения – TXT1, TXT2, TXT3 и TXT4 соответственно; FIRST – первый буфер (для считывания первых (после “мусора”) 512 байт bot-файла, FDD – второй буфер (для считывания загрузочного сектора дискеты), BUF – третий буфер (для последовательного копирования секторов из bot-файла на дискету); HANDLE – 2 байта (слово) для хранения дескриптора открытого файла.
Непосредственно после данных расположим универсальную процедуру вывода сообщений на экран. Для этой цели используем функцию 40h прерывания DOS 21h. При вызове этой функции в регистрах должны находится следующие значения:
AH – функция (40h);
BX – устройство вывода (1 – экран, 3 – внешнее устройство, 4 – печать);
CX – максимальное число байтов;
DX – адрес области данных.
Для каждого сообщения устанавливаются свои значения числа выводимых символов и адрес начала текста, общая же часть кода выглядит следующим образом:
TXT_OUT:
MOV AH,40 ; функция 40h
MOV BX,1 ; вывод на экран
INT 21 ; вызов DOS
XOR AX,AX ; устанавливаем 0 в AX для прерывания
; BIOS 16h
INT 16 ; приостановка программы - ожидание
; нажатия клавиш
CMP DX,(TXT1) ; проверка, не выводится ли 1-е
; сообщение
JE OPEN_FILE ; если да - переход к коду для
; открытия файла
; Сюда попадаем, если выводится одно из сообщений об ошибке
JMP OUT ; выход из программы
Далее следуют специфические для каждого выводимого сообщения данные:
INVITE:
MOV DX,(TXT1) ; адрес первого сообщения
MOV CX,3F ; 63 (3Fh) символа
JMP TXT_OUT ; вывести строку
FILE_ERR:
MOV DX,(TXT2) ; при ошибке открытия файла
MOV CX,17
^ JMP TXT_OUT
READ_ERR:
MOV DX,(TXT3) ; при ошибке чтения bot-файла
MOV CX,0E ; вывод лишь части TXT3
JMP TXT_OUT
READ_FDD:
MOV DX,(TXT3) ; при ошибке чтения дискеты
MOV CX,17 ; вывод всего TXT3
^ JMP TXT_OUT
WRITE_ERR:
MOV DX,(TXT4) ; при ошибке записи на дискету
MOV CX,0F
JMP TXT_OUT
Для открытия файла используется функция 3Dh прерывания DOS 21h. В регистрах должны находиться следующие значения:
AH – функция (3Dh);
AL – код доступа
(0 – для чтения, 1 – для записи, 2 – для чтения и записи);
DX – адрес строки с именем файла в ASCIIZ-формате.
В случае ошибки устанавливается флаг переноса (^ CF); при успешном открытии файла он сброшен, а в регистре AX находится дескриптор открытого файла – по нему впоследствии можно обращаться к этому файлу при операциях чтения или записи.
ASCIIZ-формат представляет собой строку в кодировке ASCII, завершающуюся двоичным нулем. Имя bot-файла будет передаваться в командной строке; как получить к нему доступ? Здесь нам придется использовать так называемый префикс программного сегмента, который операционная система размещает в памяти перед каждой COM- или EXE- программой при ее запуске. Префикс программного сегмента имеет начальное смещение 0 и размер 256 (100h) байт (именно поэтому COM-файлы начинаются со смещения 100h). Начиная со смещения 80h в префиксе программного сегмента располагается область, называемая буфером передачи данных (DTA). В первом байте этого буфера размещается длина строки параметров программы. Начиная со второго байта размещаются введенные символы (если таковые имеются), а затем следует всевозможный “мусор”.
Таким образом, в нашем случае после имени программы (wb.com) будет следовать пробел, затем имя bot-файла – по смещению 80h будет число, на 1 превышающее число букв в имени файла. Само имя начинается со смещения 82h. Этот адрес можно записать в регистр DX для функции открытия файла; однако сначала надо в конце имени файла (по смещению 81h + число символов в имени, т.е. число, хранящееся по адресу [80h]) поместить 0. Такую несколько громоздкую конструкцию закодируем следующим образом:
OPEN_FILE:
XOR BX,BX ; обнулить BX
MOV BL,[80] ; в BX - число по адресу 80h, т.е.
; число введенных символов
; (вместе с пробелом)
XOR AX,AX ; обнулить AX
MOV [BX+81],AX ; поместить 0 по адресу, равному
; сумме 81 и числа, хранящегося в BX
; - т.е. в конец имени файла
MOV AH,3D ; функция 3Dh (открыть файл)
; в AL уже находится 0 - открываем файл для чтения
MOV DX,82 ; адрес начала имени файла (без
; пробела) в DTA
INT 21 ; вызов DOS
JC FILE_ERR ; при ошибке вывести сообщение
MOV [HANDLE],AX ; сохранить дескриптор файла по
; адресу [HANDLE]
Следующим действием необходимо установить файловый указатель на значение ^ 7B00h байт от начала файла. Для управления файловым указателем предназначена функция 42h прерывания DOS 21h. В регистрах должны быть следующие значения:
AH – функция (42h);
AL – точка отсчета смещения
(0 – от начала файла,
1 – от текущего значения файлового указателя,
2 – от конца файла);
BX – дескриптор файла;
CX:DX – смещение в байтах (DX – младшее слово, CX – старшее).
При ошибке, как обычно, устанавливается флаг переноса (CF).
Итак, продолжаем:
MOV AH,42 ; функция установки файлового указателя
XOR AL,AL ; обнулить AL - отсчет смещения от начала файла
MOV BX,[HANDLE] ; дескриптор файла
XOR CX,CX ; смещение меньше 65535 - старшее слово = 0
MOV DX,7B00 ; смещение 7B00h байт
INT 21 ; вызов DOS
JC READ_ERR ; при ошибке вывести сообщение
Дальше нам нужно прочитать первые 512 байт bot-файла. Для чтения файла используется функция ^ 3Fh прерывания DOS 21h. В регистрах должны содержаться:
AH – функция (3Fh);
BX – дескриптор файла;
CX – число байтов для чтения;
DX – адрес области ввода.
При успешном выполнении функции флаг переноса ^ CF сбрасывается, а в регистре AX содержится число действительно прочитанных байтов. Если это число равно 0, достигнут конец файла. Итак:
MOV AH,3F ; функция чтения файла
; дескриптор файла сохранился в регистре BX
; после операции
; установки файлового указателя
MOV CX,200 ; 512 (200h) байт
MOV DX,(FIRST) ; адрес первого буфера
INT 21 ; вызов DOS
JC READ_ERR ; при ошибке вывести сообщение
Следующим действием считаем первый (загрузочный) сектор дискеты. Для чтения физических секторов необходимо использовать низкоуровневые функции прерывания BIOS 13h. Мы уже проделывали это при создании файла “template.bot”, поэтому это не должно вызвать проблем:
MOV SI,3 ; 3 попытки при ошибках
RETRY:
MOV AH,2 ; функция 2 - чтение
MOV AL,1 ; один сектор
MOV BX,(FDD) ; адрес второго буфера
XOR CH,CH ; дорожка 0
MOV CL,1 ; сектор 1
XOR DX,DX ; диск А: (0), головка 0
INT 13 ; вызов BIOS
JNC OK ; если все успешно, продолжить с OK
; Сюда попадаем при ошибке чтения
XOR AH,AH ; функция 0 - сброс дисковода
DEC SI ; число попыток уменьшить на 1
CMP SI,0 ;достигло 0?
JE READ_FDD ; если да, вывести сообщение об ошибке
; Сюда попадаем, если нужно еще раз попытаться прочесть сектор
INT 13 ; сброс дисковода
JMP RETRY ; новая итерация (чтение сектора)
Если чтение загрузочного сектора с дискеты было успешным, нео
еще рефераты
Еще работы по разное
Реферат по разное
Париж для семейного отдыха
17 Сентября 2013
Реферат по разное
Для начала изучим следующие вопросы
17 Сентября 2013
Реферат по разное
Предоставление услуги "Обратный вызов" для Windows 98/Me/NT/2000/XP
17 Сентября 2013
Реферат по разное
Власть в Украине не справедлива и не праведна с первых дней от создания независимого государства, т к
17 Сентября 2013