==========================================================================
RusFAQ.Ru Frequently Asked Questions
==========================================================================
Редакция
от 13.12.2003 Copyright (c)
2003 RusFAQ team
Данный
документ является подборкой ответов на наиболее популярные вопросы, задаваемые
пользователями RusFAQ.Ru (раздел "Ассемблер").
Если
Вы не нашли здесь ответа на свой вопрос, то попробуйте поискать его в книгах
П.Абеля и С.Зубкова, а также в MSDN(в том случае, если вопрос относится к
нахождению определенной функции WinAPI). Если же Вы и в них не нашли ответа, то попробуйте
задать свой вопрос на сайте www.RusFAQ.ru
Чтобы получить качественные ответы, достаточно ознакомиться со следующей краткой справкой: http://www.bobjohnson.nm.ru/faqus.html#q6
==========================================================================
Содержание:
1.
С чего начать? Какие книги и документацию посоветуете? Где их найти?
2.
Почему
я копирую текст из Зубкова, пытаюсь его скомпилировать, но вылетает куча
ошибок?
3.
Где
найти списки прерываний/ф-цийWinAPI/портов с подробным описанием?
5.
Какой
необходим инструментарий и где его найти?
6.
Как
создать COM-файл по ассемблерному исходнику?
7.
Какими
оболочками пользоваться?
8.
Можно
ли создавать программы для Win32 ДОС-овскими компиляторами.
9.
Пишу
программу для ДОС, а вместо русских букв каракули какие-то вылезают...
9.a. Моя первая программа для ДОС не работает в Windows XP
10.
Как
мне выводит на экран числа?
11.
Как
использовать ассемблерный код в языках высокого уровня?
12.
Зачем
нужен ассемблер в наше время? Каковы его преимущества перед ЯВУ?
13.
Что
можно сделать на ассемблере? Каковы его возможности?
14.
Как
работать с I/O портами, например, с LPT?
15.
Как
делать точные временные задержки, не зависящие от мощности машины?
18. Как мне производить запись в BOOT-сектор?
19.
Где
найти исходники вирусов/троянов?
20.
Где
взять документацию по SoftICE, IDA и другим отладчикам\дизассемблерам?
Сами отладчики?
21.
Как
переводить числа из одной системы счисления в другую (D<->H<->B)?
23.
Как
использовать прерывания в защищенном режиме? Как работать с графикой\текстом
из-под PM?
24.
Как
программировать звуковую карту под ДОС? А мышь?
25.
Киньте,
плиз, исходники БИОСа.
26.
Где
взять исходники прерываний BIOS\DOS?
27. Я взял код прошивки BIOS и дизассемблировал его. Фигня получается.
28.
Что
такое сопроцесcор. Как с ним работать?
29.
Как работать c ф-циями Sin/Cos/Tg/Ln/ArcSin и пр. ?
30.
Как
убрать «моргание» изображения при работе с графикой ?
31.
Как
сделать так, чтобы не работали одновременно 2 копии моей программы?
32.
Как
выдвинуть лоток CD-ROM'а
33.
Как
под Win32 работать с портами/памятью?
34.
Как
написать свой драйвер под Win32?
35.
Что
такое «кольца защиты» и зачем они нужны?
36.
Как
мне корректно подсесть на Ring-0?
37.
Как
програмировать под Linux на ассемблере?
38.
Как
заставить мой комп(или модем) работать быстрее?
40.
Что
такое RTFM, IMHO, AFAIK и другие слова, столь часто употребляемые экспертами
RusFAQ.ru?
42.
Кто
и зачем до сих пор использует DOS. Какой смысл сейчас
писать что-то для него?
==========================================================================
Q: С чего начать? Какие книги и документацию посоветуете? Где их
найти?
A:
Если Вы
начинаете с нуля (т.е. это Ваш первый язык программирования), то лучшим
вариантом является книга:
О.Калашников "Ассемблер? Это просто!"
Книга
написана живым языком и легко усваивается.
Продолжение
для программирования под Win32 лежит на
а также на
http://subscribe.ru/catalog/comp.prog.assembler
Если
же Вы являетесь опытным программистом, и уже владеете другими языками
программирования, то можно посоветовать книги:
В.Юров
"Ассемблер. Учебник" (Издательство Питер).
C.Зубков "Ассемблер - язык неограниченных возможностей"
http://www.bobjohnson.nm.ru/files/zubkov.zip
Следующая книга является
быстрым и увлекательным способом изучения языка ассемблера:
“Вирусы,
"черви", "драконы" и резиденты на службе прогресса при
изучении языка ассемблера и системы MS-DOS"
http://kalaidjian.nm.ru/tutori.rar
Также
часто советуют почитать следующие книги или
иметь их под рукой для справки:
П.Абель «Ассемблер и программирование для IBM PC»
http://www.bobjohnson.nm.ru/files/asm-abel.rar
Р.Журден "Справочник программиста на персональном
компьютере фирмы IBM"
http://www.dospage.by.ru/files/jourden.zip
Другие популярные книги см. на
http://home.od.ua/~blackw/WinAsm/winasmbooks.html
Тома Библиотеки Системного Программиста можно скачать:
В
процессе изучения да и для дальнейшей работы Вам почти точно понадобятся списки
прерываний\портов\карты памяти и пр.справочные данные из архива Ральфа Брауна,
а также справочник по WinAPI (если Вы будете программировать под Win32).
Для
программирования под Win32 часто советуют изучить «туториалы Iczelion'а»
Скачать
туториалы (с подробным разбором и комментариями) можно здесь:
http://www.wasm.ru/publist.php?list=1 (Уроки Win32API)
http://www.wasm.ru/publist.php?list=2 (Уроки PE)
http://www.wasm.ru/publist.php?list=3 (Уроки VXD)
http://www.wasm.ru/publist.php?list=4 (Уроки ODBC)
Если в процессе изучения у Вас возникли вопросы, и Вы не смогли найти на них ответ, то поищите аналогичные вопросы в архиве вопросов и ответов RusFAQ.ru:
http://rusfaq.ru/cgi-bin/search.cgi
Если
и там нет нужного Вам ответа, то задайте вопрос экспертам на http://www.RusFAQ.ru
==========================================================================
Q: Почему я копирую текст из Зубкова, пытаюсь его скомпилировать, но вылетает куча ошибок?
A: Дело в том, что приведенный выше электронный
вариант
является отсканированной версией книги, а не перепечаткой, поэтому некоторые
названия могут быть написаны русскими буквами (например имена регистров). «На
глаз» разницы не заметно, а компилятор выдает ошибку.
==========================================================================
Q: Где найти списки прерываний/ф-цийWinAPI/портов с подробным
описанием?
A:
Описание прерываний\портов\опкодов и пр.:
Справочники
по WinAPI можно взять из MSDN, RSDN.
Или
скачать:
http://learnasm.narod.ru/download/win32.rar
Если
у Вас установлен пакет Delpi или C++ Builder, то справочник можно найти в папке
C:\Program Files\Common Files\Borland
Shared\MSHelp. Правда все эти варианты только на английском. На русском
можно прочитать только обрывки:
http://www.bcbdev.ru/winapi.htm,
также можно зайти на subscribe.ru и подписаться на рассылку "Win API на
русском"
Так
что учи английский, мой читатель =)
Справочник
по
функциям
DirectX
http://learnasm.narod.ru/download/directx.rar
Справочник
по функциям OpenGL http://learnasm.narod.ru/download/opengl.rar
==========================================================================
Q: Что такое MSDN?
A:
MSDN ("Microsoft Developer Network") - на сегодняшний день крупнейший архив разнообразной
документации (описание API-функций, различная документация, технические
статьи, примеры программ и пр.). Из-за большого количества материала MSDN размещается
на нескольких компакт-дисках и требует ~2 Гб дискового пространства для полной установки.
MSDN доступен на сайте Microsoft (http://msdn.microsoft.com), но просмотр в on-line, как правило
неудобен. Microsoft дают возможность подписаться на MSDN и его обновления, (естественно за деньги, при
том довольно большие), которые будут поступать по мере выхода.
http://msdn.microsoft.com/subscriptions/ Став подписчиком, кроме
непосредственно MSDN вы будете получать также некоторые другие продукты M$
(DDK, MASM и т.д.). С января 2002 года MSDN интегрируется c MS Visual Studio.NET
Help.
В
общем, MSDN - один из инструментов, которые должен иметь каждый более-менее серьезный
программист.
==========================================================================
Q: Какой необходим инструментарий и где его найти?
A: Для разработки программ стандартным набором является:
a)
Прямые
руки, растущие из нужного места
b)
Текстовый
редактор или интегрированная оболочка для набора текста программы(см. ответ
на след. вопрос).
c) Компилятор+линковщик – набор
из программ, переводящих текст Вашей программы в машинный код и собирающих исполняемый
файл.
d) Отладчик – программа, с
помощью которой можно пошагово выполнять написанную Вам(и не только Вами =)
программу, одновременно следя за изменением содержимого стека, памяти,
регистров, флагов и т.д., с целью выявления неочевидных ошибок или просто для
наглядного представления выполнения программы. Работать с отладчиком
необязательно, но рекомендуется.
Для
начала может понадобиться пакет TASM или MASM (возможны
другие варианты компиляторов, но эти обычно рассматривается наиболее подробно,
поэтому лучше с одного из них и начать), а также отладчик TD или
AFDPRO(также возможны другие варианты, но эти наиболее простые в освоении).
TASM2.0
http://int21.narod.ru/develop/tasm.zip
Доки
к нему:
http://blackwolf2.virtualave.net/WinAsm/tasmdoc1.zip
MASM6.1
http://int21.narod.ru/develop/masm.zip
Доки
к нему:
http://int21.narod.ru/doc/masmdoc.zip
AFD, Debug, TD, DG можно скачать разом с
http://www.dospage.by.ru/files/debug.zip
Отладчик
SoftIce2.8 можно скачать с
http://www.dospage.by.ru/files/sidos-28.zip
Если
Вы решили начать программировать под Win32, то в этом случае потребуется
компилятор MASM32(см. замечание по выбору компилятора выше)
http://www.wasm.ru/tools/7/masm32v8.zip
В этот пакет входит практически всё, что может
понадобиться для программирования под Win, в том числе туториалы Iczelion’a, различные полезные примеры
программ для Win32 и многое другое.
Желающим
поработать с NASM, FASM и др. добро пожаловать на
http://www.wasm.ru/toollist.php?list=7
FASM
NASM
http://sourceforge.net/projects/nasm
==========================================================================
Q: Как создать COM-файл по ассемблерному исходнику?
A:
Процитируем
соответствующую главу из книги О.Калашникова «Ассемблер? Это просто!»:
Допустим, вы создали в текстовом редакторе файл с именем PROG.ASM.
** Если Вы используете Macro Assembler версии 5.00 – 5.10
(MASM 5.00 – 5.10):
В командной строке необходимо
указать следующее:
> MASM.EXE PROG.ASM
В результате создается файл
PROG.OBJ, который нужно слинковать при помощи компоновщика (линковщика) LINK.EXE, который
входит в комплект данного пакета:
> LINK.EXE PROG.OBJ /t
Компоновщик создаст PROG.COM, который и необходимо запускать.
Это и будет машинный код ассемблерной программы. Параметр "/t" указывает LINK.EXE, что необходимо создать файл типа COM.
** Если Вы используете Macro Assembler версии 6.11 – 6.13
(MASM 6.11 – 6.13):
В командной строке необходимо
указать следующее:
> ML.EXE PROG.ASM /AT
В результате создается два файла:
PROG.OBJ и PROG.COM. PROG.OBJ, как правило, нам больше не понадобится, и его
можно удалить, а PROG.COM запускаете на выполнение. Это и будет машинный
код ассемблерной программы. Параметр "/AT" указывает программе-ассемблеру (MASM), что после ассемблирования, в случае, если
ошибок не будет обнаружено, следует запустить компоновщик (LINK.EXE) и
передать ему параметры для создания файла типа COM.
Обратите внимание, что
параметр "/AT"
должен быть указан ЗАГЛАВНЫМИ символами!
** Если Вы используете Turbo Assembler (TASM):
В командной строке необходимо
указать следующее:
Если prog.asm не содержит ошибок,
то в результате создается файл PROG.OBJ, который нужно скомпоновать при помощи
компоновщика (линковщика) TLINK.EXE:
> TLINK.EXE PROG.OBJ /t
TLINK.EXE создаст
файл PROG.COM, который и нужно запустить на выполнение. Параметр "/t" указывает TLINK.EXE, что необходимо создать файл типа COM.
==========================================================================
Q: Какими оболочками пользоваться?
A: Это вопрос вкуса. Многие программисты не используют
дополнительные оболочки вообще. Т.е. программа набирается в FAR, Norton Commander, Bred2 или
любом другом текстовом редакторе и сохраняется в определенной
Вами рабочей папке. Затем запускается пакетный BAT-файл, который помещается в одну
папку с компилируемой программой. Например такой батник можно использовать для
сборки и запуска программ для Win32:
--run.bat----------------------------------------
@echo
off
REM Путь к компилятору и линковщику. Подкорректируйте для Вашего случая.
SET PROGPATH =
c:\masm32\bin
if
exist %1.obj del %1.obj
if
exist %1.exe del %1.exe
REM компилируем:
%PROGPATH%\ml /c /coff /nologo %1.asm
REM Линкуем:
%PROGPATH%\Link /SUBSYSTEM:WINDOWS /MERGE:.rdata=.text %1.obj > nul
del
%1.obj
REM
Запускаем:
%1
-------------------------------------------------
Теперь
Вам достаточно написать в командной строке:
>
RUN PROG
И
Вы получите программу prog.exe, которая тут же и
запустится.
Если же Вы привыкли к интегрированным оболочкам, типа тех, что поставляются с Turbo Pascal,
TD и пр., то воспользуйтесь оболочкой Turbo Shell Сергея Чехуты
Для
начинающих это самое оно – программа имеет множество удобных опций, как работа
с мышью, меню, интерактивный интерфейс и пр.
==========================================================================
Q: Можно ли создавать
программы для Win32 ДОС-овскими компиляторами?
A:
Нет
==========================================================================
Q: Пишу программу для ДОС, а вместо русских букв каракули какие-то
вылезают...
A:
1. Скорее всего Вы пишете не в
DOS-кодировке, а в Win-1251(например в Блокноте). Используйте редакторы
Bred2(заменитель Блокнота с возможностями перекодировки) или
FAR - там можно изменять кодировку в редакторе нажатием F8.
2. Если это не помогло
(например, если у Вас англоязычная ОС), установите руссификатор, например,
KeyRus.
==========================================================================
Q: Моя первая программа для ДОС не работает в Windows XP
A:
В самом начале исходника программы поставьте переход в текстовый видеорежим:
mov ax,03h
int 10h
==========================================================================
Q: Как мне выводит на экран числа?
A: Перед выводом на экран
число следует разбить на цифры и каждую цифру выводить отдельно, при этом
прибавляя к каждой из них 30h. Обратите внимание на таблицу ASCII – числам
соответствует ряд, начинающийся с 30h.
Вот пример такой программы(для простоты использован сопроцессор):
--writeint.asm-----------------------------------
.387
;Используем сопроцессор
.model small
.data
chislo dw 9000
;Число для вывода
cifra dw ?
delitel dw 10
.code
main:
push @data
;Инициализация сегмента данных
pop ds
xor cx, cx
;Обнулим СХ
finit
;Инициализация сопроцессора
cycle:
fild delitel
;Загрузим делитель (т.е. 10)
fild chislo
;Загрузим число для вывода
fprem
;Получим остаток от деления
fistp cifra
;и выгрузим его в cifra
fild chislo
;Загрузим число для вывода
fidiv delitel
;Разделим на 10
fistp chislo
;Выгрузим частное от деления на место изначального числа
cmp cifra, 5
;Корректируем результат округления
jb lab
dec chislo
lab:
push cifra
;Сохраним цифру в стеке
inc cx
;И увеличим счетчик разрядов
mov ax, chislo
test ax, ax
jnz cycle
;Если число еще не ноль, то повторим
sub_loop:
;Вывод на экран
pop ax
add ax, 30h
int 29h
loop sub_loop
mov ah, 4ch
;Выход и возвращение
управления ОС
int 21h
end main
-------------------------------------------------
Работу программы полезно
проследить в отладчике, например в TD.
(окно стека сопроцессора у
последнего можно вызвать с помощью пункта меню View->NumericProcessor)
==========================================================================
Q: Как использовать ассемблерный код в ЯВУ
A:
1. Ассемблерными вставками или операторами типа inline(машинный код).
Такой
способ подразумевает вставку ассемблерного кода в виде команд ассемблера или
машинных кодов прямо в текст программы на ЯВУ. Этот способ удобен, если нужно
использовать небольшие фрагменты ассемблерного кода.
В Паскале:
Asm
... тут Ваш текст...
End;
Например:
--primer.pas-------------------------------------
BEGIN
asm
xor ah, ah
int 16h
end;
END.
-------------------------------------------------
Ассемблерная процедура
оформляется так:
Procedure myproc; assembler;
Asm
...тут Ваш текст...
End;
В С/С++:
_asm{ ... тут Ваш текст... }
2. Используя внешние ф-ции
или процедуры.
В этом случае ассемблерный код оформляется в виде текста отдельной программы,
котоую можно компилировать и отлаживать независимо от основной программы на
ЯВУ.
Передача
аргументов происходит через стек. При этом в Паскале аргументы ф-ции или
процедуры передаются в стек слева направо (т.е. в вершине стека оказывается
крайний справа аргумент), а в С\С++ справа налево.
Перейдем
сразу к примеру. Предположим, что нам нужна программа на Паскале, использующая
ассемблерный код для вывода на экран символа.
Модифицированный
пример из Юрова:
--pas_asm.pas------------------------------------
uses CRT;
{$D+}
{включение полной информации для отладчика}
procedure
asmproc(ch: char; x, y, kol:integer); external;
{ch - символ, x, y – координаты, kol - число выводов}
{процедура обявлена как
внешняя (external)}
{$L asm_pas.obj}
BEGIN
clrscr; {очистим экран}
asmproc('O', 1, 4, 5);
asmproc('K', 9, 2, 7);
END.
-------------------------------------------------
--asm_pas.asm------------------------------------
MASM
.model
small
.stack
256
.code
asmproc proc near
PUBLIC
asmproc ;объявлена как внешняя
push bp ;пролог
mov bp, sp
; позиционирование
курсора:
mov ah,
02h ;номер ф-ции
mov dh,[bp+6] ;dh = y
mov dl,[bp+8] ;dl = x
int 10h
; вывод символа:
mov ah, 09h ;номер ф-ции
mov al,[bp+10] ;al = ASCII код символа
mov bl,
07h
;bl = цвет
символа и заднего фона (атрибут)
mov bh, 0 ;bh = номер
видеостраницы
mov cx,[bp+4] ;cx = число выводов
int 10h
pop bp
ret 8 ;очистка стека (8байт) и возврат из процедуры
asmproc endp
end
-------------------------------------------------
asm_pas.asm
следует скомпилировать:
>
tasm asm_pas.asm
Получившийся в результате asm_pas.obj
положите в папку с pas_asm.pas и окомпилируйте pas_asm.pas
Чтобы
стал понятен принцип обмена аргументами, рассмотрим фрагмент стека после выполнения
команд пролога:
...
+---------+
| bp
| <- Вершина стека (ss:sp=ss:bp).
Результат команды push bp
+---------+
| ip
| <- ss :
[bp + 2] Результат команды call asmproc
+---------+
| kol
| <- bp + 4
+---------+
| y
| <- bp + 6
+---------+
| x
| <- bp + 8
+---------+
| ch
| <- bp + 10
+---------+
|Дно
стека| <- ss:ffff
+---------+
...
При работе с с\с++
мы бы заметили обратный
порядок заполнения стека аргументами.
Теперь рассмотрим более "культурный" вариант программы на ассемблере
с применением директивы ARG (подробнее читайте у Юрова):
--asm_pas.asm------------------------------------
MASM
.model
small
.stack
256
.code
asmproc proc near
arg kol:WORD, y:WORD, x:WORD, chr:BYTE=a_size
;в
a_size лежит число байт, занятых аргументами
PUBLIC
asmproc ;объявлена как внешняя
push bp ;пролог
mov bp, sp
;
позиционирование курсора:
mov ah,
02h ;номер ф-ции
mov dh, byte ptr y
mov dl, byte ptr x
int 10h
; вывод символа:
mov ah, 09h ;номер ф-ции
mov al, chr ;al = ASCII код символа
mov bl,
07h
;bl = цвет
символа и заднего фона (атрибут)
mov bh, 0 ;bh = номер
видеостраницы
mov cx,
kol
;cx = число выводов
int 10h
pop bp
ret a_size ;очистка стека и возврат из процедуры
asmproc endp
end
-------------------------------------------------
Подробно о связи ассемблера с языками высокого уровня
можно прочитать у В.Юрова.
==========================================================================
Q: Зачем нужен ассемблер в наше время? Каковы его преимущества
перед ЯВУ?
A: Эта вечная темя для споров,
а посему то, что написано ниже, конечно же, является специфическим мнением
автора и подлежит критике. Подробно этот вопрос рассматривался на сайте http://www.assembler.ru
,
который
существует на данный момент лишь в виде архивов, разбросанных в сети.
Итак. Ассемблер в основном используется
для решения различных нестандартных задач, встающих перед программистами,
например, работа с нестандартным железом (самопальным, например), оптимизация
работы программ, написание драйверов.
Ассемблер используется в критичных к
скорости выполнения программах, а также в программах, монополизирующих ресурсы
системы(наприемер в программах, производящих различные вычисления, переборы,
сортировки, работющих с графикой).
В тоже время нельзя противопоставлять
ассемблер языкам высокого уровня, наоборот, следует их использовать в связке –
визуальные элементы составлять на ЯВУ, а некоторые специфичные ф-ции писать на
ассемеблере.
Желающим
подробно почитать по теме можно предложить
Great
Debate by Randell Hyde.
Зачем изучать ассемблер?
Ответ на этот вопрос можно
найти в ASM FAQ by Bob Johnson:
-- http://www.bobjohnson.nm.ru/faqus.html--------
Знание
ассемблера необходимо для понимания принципа работы процессора вообще - т.к.
это значительно повышает уровень програмиста в целом, даже если он не пишет
ничего на ассемблере, а использует С++. Знание ассемблера позволяет понять, как
процессор обрабатывает данные, команды, какие у него есть возможности и как их
можно использовать. Это, в свою очередь, позволяет лучше организовать структуру
программы даже на другом языке программирования (особенно - С++), потому что
изучив ассемблер программист уже представляет себе, как поставленную задачу
можно решить на нем, т.е. в каком виде ее должен представить компилятор того же
С++ (ведь процессор воспринимает только машинные коды, в которые переводит Вашу
программу компилятор, а машинные коды полностью эквиваленты ассемблеру). А это
позволяет лучше организовать программу и на языке высокого уровня.
Кроме того,
знание ассемблера необходимо, если Вы собираетесь разобраться в уже готовой
чужой программе, т.к. в 99,9% случаев к таким программам нет исходных текстов,
а есть только готовый исполняемый файл. А когда Вы "влезете" в этот
файл отладчиком, то единственное, что вы увидете - будет ассемблер и байты
данных.
Но, к
сожалению, популярность ассемблера постепенно падает, что прежде всего
происходит из-за того, что ассемблер - достаточно сложный и полностью
платформеннозависимый язык. Первое требует от программиста большого объема
знаний, а второе не позволяет легко переносить программу на ассемблере с одной
платформы (процессора) на другую.
Тем не менее,
есть вещи, которые никогда не писались и не будут писаться на языках, отличных
от ассемблера - это прежде всего ядро операционной системы и большая часть
драйверов. Потому что именно здесь необходимо использовать все ресурсы
процессора "по максимуму", а никакой другой язык программирования
этого не позволяет.
-------------------------------------------------
==========================================================================
Q: Что можно сделать на ассемблере?
Каковы его возможности?
А: Сделать можно абсолютно любые
программы – начиная с Вашего любимого браузера и заканчивая ОС. Более того на
ассемблере можно программировать не только компьютеры, но и калькуляторы и
любые другие микропроцессорные системы. Единственное, что набор машинных
комманд для различных процессоров различен, а следовательно и ассемблерные
языки различны, однако сам факт возможности программирования на ассемблере
присутствует.
==========================================================================
Q: Как работать с I/O портами, например, с LPT?
A: Тема
подробно разбирается в статье Тиграна Калайджяна: “Программирование I/O
устройств для управления внешними схемами"
http://kalaidjian.nm.ru/proekt.rar
Статья
написана специально для пользователей RusFAQ.ru. Аналогов в Рунете нет.
Также
смотрите:
1.
О.Калашников, С.Гуляев, Ю.Новиков "Разработка устройств
сопряжения для персонального компьютера типа IBM PC"
Электронную версию см. тут:
http://www.cepera.h1.ru/
2.
"Ответы на вопросы о периферии" http://www.svtehs.com/ru/embint.htm
3.
Одная из лучших книг по теме:
Пей
Ан «Сопряжение ПК с внешними устройствами» (Издательство Newnes-на английском
языке или ДМК – на русском
языке). Электронной версии пока нет, купите "бумажную" – она того
стоит!
==========================================================================
Q: Как делать точные временные задержки, не зависящие от
мощности машины?
A:
1. Под ДОС (не менее 1000мкс):
...
mov ah, 86h
mov cx, число_секунд
mov dx, число_микросекунд
int 15h
...
2. Под ДОС (не менее 55мс). Используется счётчик таймера
(0000h:046Сh)
...
xor ax, ax
mov es, ax
mov eax, es:[Addr]
add eax, Delay
m1:
cmp es:[Addr],eax
jb m1
...
;значение
задержки в миллисекундах, деленное на 55
Delay equ 100
Addr equ 046Ch ;адрес памяти счетчика тиков
таймера
...
3. Под ДОС (используем
значение счетчика времени суток BIOS):
;получение значения счетчика
и установка задержки
mov ah,0
;номер функции для "чтения"
int 1ah
;получаем значение счетчика
add dx,91
;добавляем 5 сек. к младшему слову
mov bx,dx
;запоминаем требуемое значение в bx
;постоянная проверка
значения счетчика времени суток bios
repeat:
int 1ah
;получаем значение счетчика
cmp dx,bx
;сравниваем с искомым
jne repeat ;если неравен, то повторяем снова
;иначе, задержка окончена
4. Под Win:
...
push число_миллисекунд
call sleep
...
5. Под Win (высокая точность) для FASM:
--delay.asm--------------------------------------
format PE GUI
entry start
section '.code' code
readable executable
start: finit ;Инициализация сопроцессора
emms ;Подготовка
сопроцессора к операциям с
;плавающей точкой
;т.е. освободить регистры ММХ
rdtsc ;EDX:EAX
= Текущее число тактов
;с момента последнего сброса
процессора
push eax
push 1000 ;Временная задержка на 1сек.
call [Sleep]
rdtsc ;EDX:EAX
= Текущее число тактов
;с момента последнего сброса
процессора
pop ebx ;EBX = Текущее число тактов
sub eax, ebx ;EAX = EAX - EBX (частота
процессора)
push eax
fild dword [esp] ;ST(1) = EAX (т.е. вершина стека)
fild dword [mil] ;ST(0) = mul = 1000
fdivp st1, st0 ;ST(0) = ST(1) / ST(0)
frndint ;Округлить
до целого числа ST(0)
fild dword [req_delay] ;ST(1) = ST(0), ST(0) = req_delay
= 15000
fmulp st1, st0 ;ST(0) = ST(0) * ST(1)
push eax
push eax
fistp qword [esp] ;Запихать ST(0) в стек
pop ebx
pop ecx
pushad ;Запихать в стек все 32-битные регистры
push 1010h
push szCapt
push szStart
push 0
call [MessageBoxA] ;Показ диалога
popad ;Вынуть
из стека все 32-битные регистры
rdtsc
push edx
push eax
fild qword
[esp] ;ST(0) = вершина стека
@@:
rdtsc
push edx
push eax
fild qword
[esp] ;ST(1) = ST(0), ST(0) = вершина стека
add esp, 8
fsub st0, st1 ;ST(0) = ST(0) - ST(1)
push ecx
push ebx
fild qword
[esp] ;ST(0) = вершина стека
pop ebx
pop ecx
fcomip st0, st1 ;Сравнить, установить CF и вытолкнуть
fistp dword [esp]
;Вытолкнуть в стек
jnc @B ;Прыгаем на @@, если ST(0) >= ST(1)
push 1010h
push szCapt
push szEnd
push 0
call [MessageBoxA] ;Показ диалога
exit:
push 0
call
[ExitProcess] ;Выход
section '.data' data
readable writeable
szCapt db "Delay", 0
szStart db
"Press OK to start...", 0
szEnd
db
"Finished.", 0
mil
dd 1000
req_delay
dd 15000 ;Задержка
section '.idata' import data
readable writeable
dd
RVA kernel_table, 0, 0, RVA kernel_name, RVA kernel_table
dd RVA user_table, 0, 0, RVA user_name, RVA user_table
dd 0, 0, 0, 0, 0
kernel_table:
ExitProcess dd RVA _ExitProcess
Sleep dd RVA _sleep
dd 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0
_MessageBoxA dw 0
db "MessageBoxA",0
_sleep: dw 0
db "Sleep", 0
_ExitProcess dw 0
db "ExitProcess", 0
kernel_name db
'KERNEL32.DLL',0
user_name
db "USER32.DLL", 0
-------------------------------------------------
Эта программа будет работать только на процессорах
Pentium, Celeron, AMD K6-2 или выше. Это связано с командой rdtsc, появившейся
относительно недавно.
==========================================================================
Q: Как завесить машину?
A:
Предложим несколько
вариантов:
1. Win9x (запрет прерываний
в бесконечном цикле)
...
cli
jmp $-2
...
2. WinNT (консоль)
...
fool dd 0
...
mov
eax, 0a0h
mov edx, [Fool]
int 2Eh
...
3. WinNT
(программа должна быть запущена пользователем с правом Increase
Scheduling Priority)
...
m1:
push REALTIME_PRIORITY_CLASS
call SetPriorityClass
jmp m1
...
4. WinNT. Планировщик
OS ничего не знает о процессах, он распределяет время между потоками. По этой
причине если у одной программы потоков будет на порядок больше чем у другой, то
все процессы, кроме нашего, фактически не получат время. Вот реализация этой
идеи (для простоты на C):
DWORD ThreadProc(LPDWORD)
{
while(TRUE);
return 0;
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR szLine,int Cmd)
{
DWORD dwResult;
SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
while(TRUE)
{
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&dwResult);
}
return 0;
}
5. WinNT.
Создаем кучу WDM, и забиваем
тем самым память. BAT-файл может запускаться программой.
--pushit.bat-------------------------------------
rem "рекурсивный" пакетный файл
start pushit.bat
start pushit.bat
-------------------------------------------------
6.
WinNT. Откроем максимально возможное количество классов
окон. Тогда у наc не получится вызвать Task Manager, т.к. для этого нужно
зарагистрировать еще один
класс =)
Пример
на С (опять же для простоты) см. ниже:
...
int WINAPI WinMain(HINSTANCE
hInst,HINSTANCE hPerv,LPSTR lpszCmd,int Cmd)
{
int i,j;
char szFool[0x40];
WNDCLASS wc;
for(i=0;;i++)
{
srand(i);
for(j=0;j < 0x20;j++) szFool[j]=(rand() >> 7) & 0xFF;
szFool[0x20]=0;
wc.style = NULL;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = szFool;
RegisterClass(&wc);
}
}
...
7. OS/2. Запись в своп.
--OS2cool.bat------------------------------------
echo
FoolPlainText > swapper.dat
rem
swapper.dat - файл подкачки OS/2.
-------------------------------------------------
8.
UNIX.
Запустить
в фоне.
--hangunix---------------------------------------
cat
hangunix > x
cat x >> hangunix
./hangunix &
./hangunix &
-------------------------------------------------
9. UNIX. Вызывайте ф-ию fork() в бесконечном цикле.
10. DOS (Но не DosPromt в Win !):
a) Переводим микропроцессор в состояние останова.
...
hlt
...
b) Бесконечный цикл.
...
m1:
jmp m1
...
c) Запрет прерываний
...
cli
...
d) Практически любая некорректная операция
=) Можно прыгнуть по
произвольному адресу памяти и посмотреть,
что из этого получится =)
Например, прыжок в 0000:0000
наглухо вешает машину
11. Win16. Поставить бесконечный цикл в процедуре окна.
==========================================================================
Q: Как перезагрузить машину?
A: Железный
вариант – кнопка RESET =)
Программные варианты:
1. Из-под ДОС (Но не DosPromt в Win !):
a) Сброс процессора
mov al, 0feh
out 64h, al
b) Прыжок по адресу fff0h:0f00h
db 0eah ; jmp
dd 0f000FFF0h
c) Вызов int 18h
d) Вызов int 19h
2. Из-под Win9x(использовался MASM32):
--reboot.asm-------------------------------------
.386
.model flat, stdcall
option casemap :none ; case sensitive
include
\masm32\include\windows.inc
include
\masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib
\masm32\lib\user32.lib
includelib
\masm32\lib\kernel32.lib
.code
start:
invoke ExitWindowsEx,1 or EWX_REBOOT,0
invoke ExitProcess,eax
end start
; Флаги для
ExitWindowEx
; EWX_LOGOFF equ 0
; EWX_SHUTDOWN equ 1
; EWX_REBOOT equ 2
; EWX_FORCE equ 4
; EWX_POWEROFF equ 8
-------------------------------------------------
2. Из-под Win9x(использовался MASM32):
-------------------------------------------------
.386
.model flat, stdcall
option casemap :none ; case sensitive
include masm32\include\windows.inc
include masm32\include\user32.inc
include masm32\include\kernel32.inc
include masm32\include\advapi32.inc
includelib masm32\lib\user32.lib
includelib masm32\lib\kernel32.lib
includelib masm32\lib\advapi32.lib
.data
hToken dd 0
tp TOKEN_PRIVILEGES <>
old_tp TOKEN_PRIVILEGES <>
lpName db 'SeShutdownPrivilege',0
old_tp_buff_need dd 0
.code
start:
invoke GetCurrentProcess
invoke OpenProcessToken, eax, TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY, ADDR hToken
invoke LookupPrivilegeValue, 0, ADDR lpName, ADDR tp.Privileges[0].Luid
mov tp.PrivilegeCount, 1
mov tp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED
;invoke AdjustTokenPrivileges, hToken, FALSE, ADDR tp, 0, NULL, 0
invoke AdjustTokenPrivileges, hToken, FALSE, ADDR tp, sizeof old_tp,ADDR old_tp,
ADDR old_tp_buff_need
mov eax,old_tp_buff_need
invoke ExitWindowsEx, EWX_REBOOT,0
invoke ExitProcess, 0
end start
-------------------------------------------------
==========================================================================
Q: Как мне производить запись в BOOT-сектор?
A: Ниже следует программа, которая записывает в BOOT-сектор часть своего тела, как отдельную программу. Только надо учесть, что не всякую программу можно туда положить. Недоступность прерываний(за редким исключением) – только одна из проблем, следует учитывать размер записи (не более 512 байт) и пр. А вообще, если хотите поработать с BOOT-сектором, было бы неплохо учиться этому на основе изучения вирусов.
Итак, программа:
--makeboot.asm-----------------------------------
;****************************************************************
;* Пример программы, пишушей в БУТ-сектор
дискеты *
;*Вставьте дискету, запустите программу и загрузитесь с дискеты *
;****************************************************************
.model small
.stack
.data
; 0 = Дисковод A:
; 1 = Дисковод B:
laufwerk equ 0
;----------------------------------------------------------
; Хранилище под один сектор (размер занимаемой памяти 512b)
;----------------------------------------------------------
puffer db 16h dup (?)
fatsek dw ?
;Partition Table
db 2bh-18h dup (?)
laderstart db 200h-2bh dup (?)
;Загрузчик системы
;----------------------------------------------------------
; Программа записи
;----------------------------------------------------------
.code
start: mov ax,@data
;Инициализация сегмента
mov ds,ax
;данных
mov dx,0
;Стартовый сектор (BOOT)
mov cx,1
;Число секторов для чтения: 1
mov bx,offset puffer
;Адрес буфера в DS:BX
mov al,laufwerk
;Номер дисковода(A:)
int 25h
;Считать в хранилище!
mov cx,3
;Занести 3 байта от
mov si,offset bootsektor
;Начала нашего "сектора"
mov di,offset puffer
;В буфер
aenderesprungziel:
mov al,cs:[si]
;Копирование байта
mov ds:[di],al
;CS:[si]->DS:[di]
inc di
inc si
loop aenderesprungziel
;Лупим, пока CX > 0
mov cx,laderoutinelaenge
;В CX размер данных
mov di,offset laderstart
;Адрес буфера кода
mov si,offset startroutine
;Смещение загруз. кода
aenderelader:
mov al,cs:[si]
;Копирование байта
mov ds:[di],al
;CS:[si]->DS:[di]
inc di
inc si
loop aenderelader
;Лупим, пока CX > 0
mov dx,0
;Стартовый номер сектора
mov al,laufwerk
;Номер дисковода
mov bx,offset puffer
;Адрес буфера
mov cx,1
;Число секторов
int 26h
;ЗАПИСАТЬ !
abbruch: mov ah,4ch
;Возврат управления
int 21h
;Опер. системе
;----------------------------------------------------------
; Вот то, что мы будем сажать
;----------------------------------------------------------
bootsektor:
jmp short startroutine
;Перепрыгнуть
nop
;на загрузчик системы
dummy db 28h dup (?)
;Здесь как будто сидит
;Partition Table, на
;самом деле нужно только
;для правильного форми-
;рования адреса прыжка
startroutine:
cli
;Запрет прерываний
mov bx,cs
mov ss, bx
;SS=DS
mov sp, 7c00h
;Программный код
mov ds,bx
;DS=CS
sti
;Разрешение прерываний
mov si,7c00h+textstart
;В SI адрес строки
zeichen: lodsb
;Пересылка элемента
;строки в AL
cmp al,'$'
;Конец строки?
je textfertig
;Если да,то выход из цикла
mov bx,7
;Если нет, то вывод
mov ah,0Eh
;В AL-символ
int 10h
;Вывести его на дисплей!
jmp short zeichen
;Прыгаем вверх
textfertig:
;Холстой цикл
jmp short textfertig
;Вешаем систему
;----------------------------------------------------------
; Область данных и строка для вывода
;----------------------------------------------------------
textstart equ $-bootsektor+0
db 'Hello from Tigran!$'
;----------------------------------------------------------
; Конец области для записи в BOOT-сектор
;----------------------------------------------------------
laderoutinelaenge equ $-startroutine+0
end start
-------------------------------------------------
==========================================================================
Q: Где найти исходники вирусов/троянов?
A: Дело в том, что сайты,
содержащие эту информацию долго не живут, но есть некоторые «устойчивые»
экземпляры, и всё же будьте готовы, что нижеследующие линки уже будут мертвыми
к моменту выхода FAQ
Итак:
http://www.wasm.ru/publist.php?list=6
http://www.viruslist.com
– большой
справочник
с описанием различных вирусов (без исходников). Постоянно обновляется.
Далее Вы можете скачать Файлы с http://kalaidjian.w6.ru :
Имя некоторых файлов нужно кое-как подправить (защита от дурака)
tutori.zip | 80K | Изучение Ассемблера на примере написания вирусов. Книга написана живым языком. ВСЕМ СОВЕТУЮ ! Читать под ДОС |
cih.rar | 16K | Полный исходник Чернобыля с комментариями |
vir2.rar | 63K | Игорь Коваль <Как написать компьютерный вирус> |
vgw32.rar | 311K | Руководство по написанию 32-битных вирусов. Очень подробно. |
VIRBEZR.RAR | 404K | Н.Н. Безруков. Компьютерная вирусология |
VIRBURG.RAR | 208K | Ральф Бургер. Большой справочник по компьютерным вирусам |
virsim.zip | 113K | Исходные тексты 34 вирусов: 196, разновидности Anti-Pascal, Highlander, Intrudder, Joshua, Leprosy-B, разновидности Tiny, V2100, Vienna и др. |
bootvir.rar | 5K | Бут-вирус под виндовс98: старые звери в новом лесу (c) Chingachguk/HI-TECH |
bw100.rar | 38K | Генератор вирусов (АСМ) |
VBSworm.rar | 8K | Пишем червь на VBS |
virii.rar | 7K | Пишем макро-вирус |
psy.rar | 4K | Психологические вирусы |
klexa.rar | 161K | Клещ для Windows. Внедряемся в систему. |
dvl1.rar | 120K | “Duke's Virus Labs” Выпуск 1 - журнал для начинающих Вирмейкеров |
backDoor.rar | 11K | Как написать Backdoor |
troyan.rar | 75K | Как написать свой троян |
zhello.zip | 13K | ZHello virus |
18.rar | 418B | Trojan.18 - non-TSR, MBR/BOOT/CMOS-overwriter ;-) |
32.rar | 536B | Z0MBiE.32 - TSR, EXE-overwriter |
bitmask.rar | 4K | О дисассемблировании и битовых масках |
enuns.zip | 22K | ENUNS infection |
heur.rar | 4K | О том, как обмануть эвристик |
hllexmpl.zip | 8K | pascal HLL virus example |
hlp.zip | 36K | Заражение HLP-файлов справки. |
hooy.zip | 38K | win9X.Hooy virus |
inf1sec.zip | 9K | FIRST SECTION FILE INFECTOR |
ircworm.rar | 2K | О некоторых методах распространения вирусов |
lde106_x.zip | 9K | win9X.LDE.Examplo virus |
m1.zip | 61K | M1 virus |
rndvir.rar | 6K | ГСЧ В ВИРУСАХ |
selfcorr.rar | 3K | Помехозащищенные вирусы |
tp_com.zip | 16K | TP_COM virus |
undetect.rar | 6K | Недетектируемые вирусы |
vxd.zip | 32K | Заражаем VxD |
w9xshare.rar | 1K | Win9X: Пишем в закрытые для записи файлы |
w9x-tiny.zip | 54K | win9X.132,133,134,140,142,148,149,150,151, 152,159,161,162,166,170,180,a,182,184,185,187,189, 190,a,197,200,204,b,206,209,218,223,230,242 virii(akaWin95.SillyWR.nnn) |
win32vir.rar | 16K | Вирусы под Win32 FAQ |
win32vir.zip | 7K | win9X.Examplo virus |
z0mbie1.zip | 114K | win95.Zombie |
z0mbie2.zip | 63K | win9X.Z0MBiE-II (Twinny) virus |
z0mbie3.zip | 5K | win9X.Z0MBiE-4 (Zofo) |
z0mbie4.zip | 8K | win9X.Z0MBiE-3 virus |
z0mbie4b.zip | 37K | win9X.KME.Z0MBiE-4.b (ZMorph) virus |
z0mbie4c.zip | 36K | win9X.Z0MBiE-4.c (ZMorph) virus |
z0mbie4d.zip | 15K | win9X.Z0MBiE-4.d (ZoM) virus |
z0mbie5.zip | 99K | Z0MBiE-5 (W95.Bistro) virus |
z0mbie6a.zip | 41K | win9X.RPME.Z0MBiE-6.a (ZPerm) virus (win9x permutatingz0mbie6b.zip 48K+ Z0MBiE-6.b virus (win9x polymorphic(CODEGEN)+permutating(RPME)) |
z0mbie7.zip | 27K | win9X.Z0MBiE-7 (ZPerm) permutating virus |
z0mbie8.zip | 15K | win98.Z0MBiE-8 (Damm) virus |
007.zip | 25K | 007JB virus |
Данные файлы были скачаны с различных сайтов и
станций ББС, так что авторы статей могут (при желании) предъявить претензии
автору данного FAQ при их несогласии с опубликовыванием здесь ссылок на их
статьи без их согласия.
Также хочу напомнить, что автор данного FAQ не
несет ответственности за вред, причиненный в результате использования данных
статей и программ. Также автор не несет ответственности за содержание статей.
==========================================================================
Q: Где взять документацию по SoftICE, IDA и другим
отладчикам\дизассемблерам? Сами отладчики.
A: Софт смотрите здесь(колонка слева):
http://www.wasm.ru/toollist.php
На том же сайте можно найти примеры работы с этими программами.
Стабильный SoftIce для XP:
http://reversing.kulichki.net/files/debug/sinstallnt.exe
патчи тут:
http://reversing.kulichki.net/files/debug/debug.htm
Из документации можно порекомендовать:
Крис Касперски «Образ мышления IDA» http://www.bobjohnson.nm.ru/files/IDA.rar
Толстое руководство (около 900К) на русском к SoftICE можно скачать:
ftp://shelek.no-ip.com/manuals/softiceru.zip
Также
посмотрите следующие наиболее частые вопросы по SoftIce,
может найдете среди них свой:
1. Какую версию
использовать?
Лучше
всего использовать SoftIce из DS 2.7 (ftp://ftp.exetools.com)
или DS 2.6 Под Win9x/NT также SoftIce 4.05, под
2k/XP стабильно
работает только DS 2.7. Установка различных патчей не
рекомендуется,
тем более, что DS2.7 весит не очень много - ~40 Мб.
2. Не работает Symbol Loader из DS2.7
Для
исправления этого нужно в файле SoftICE\nmtrans.dll изменить байт
по смещению 0x1CD7A с 0xB8 на 0x25.
3. Какой видеоадаптер выбирать?
Universal
Video Driver. Если не нравится, что сайс
появляется в
слишком маленьком окне, то можно его расширить:
set font 2
lines 60
width 160
или
SET MAXIMIZE ON
При этом может потребоваться увеличить video memory size.
4. Почему не срабатывают breakpaoint'ы
на api в некоторых программах,
например GetWindowTextA?
а) Возможно используется GetWindowTextW
или GetDlgItemTextA.
б) Может использоваться WM_GETTEXT
(к примеру). В этом случае следует
попробовать поставить breakpoint
на сообщение (bmsg).
в) Возможно, программа использует свои контролы вместо стандартных.
г) Может быть, проблема в версии SoftIce. Например, SoftIce
4.05 +
патч для WinXP иногда
игнорирует бряки и вообще работает нестабильно.
5. Как посмотреть стек?
dd ss:esp
Можно создать еще одно окно и привязать ss:esp к нему.
wd.1
dex 1 ss:esp
==========================================================================
Q: Как переводить числа из одной системы счисления в другую
(D<->H<->B)?
A: Чтобы не запутаться в с.с. будем приписывать справа к числу
соответствующую букву:
b (BIN) – двоичная
с.с. – основание системы: 2
d (DEC) –
десятичная
с.с. - основание системы: 10
h (HEX) –
шестнадцатеричная с.с. -
основание системы: 16
Для
перевода DEC->HEX следует
последовательно делить число на 16 и записывать остатки в разряды нужного нам
шестнадцателичного представления. Вот пример(в скобках мы будем записывать
остатки):
42623/16 = 2663(15) F (15d=Fh) – младший
разряд
2663/16 = 166(7) 7
166/16 = 10(6) 6
10/16 = 0(10) A (10d
= Ah) –
старший
разряд
------------------------------------------
Итого: 42623d
= A67Fh
Тут нам понадобилась таблица
соответствия чисел:
0h -> 0d -> 0b
1h -> 1d -> 1b
2h -> 2d -> 10b
3h -> 3d -> 11b
4h -> 4d ->
100b
5h -> 5d ->
101b
6h -> 6d ->
110b
7h -> 7d
-> 111b
8h -> 8d ->
1000b
9h -> 9d ->
1001b
Ah -> 10d
-> 1010b
Bh -> 11d -> 1011b
Ch -> 12d -> 1100b
Dh -> 13d -> 1101b
Eh -> 14d -> 1110b
Fh -> 15d -> 1111b
Как видите, тут ничего сложного нет. Перевод DEC->BIN происходит по той же схеме,
только
число
делится не на 16, а на 2 (т.е. на основание данной позиционной с.с. Для
восмеричной мы делили бы на 8, для троичной на 3 и т.д.)
Что
касается перевода HEX->DEC, то
это можно сделать следующим образом:
Возьмем
16-ричное число. Сумма=0.
Берем
последнюю цифру и умножаем на 16 в степени 0(т.е. на 1). Прибавляем к сумме.
Берем
предпоследнюю цифру и умножаем на 16 в степени 1. Прибавляем к сумме.
Берем
предпредпоследнюю цифру и умножаем на 16 в степени 2, Прибавляем к сумме.
.
.
.
Берем
первую цифру и умножаем на 16 в степени (n-1), где n-число разрядов
16-ричного
числа. Прибавляем к сумме.
В
сумме будет лежать DEC-число, эквивалентное данному.
Пример:
F1Ah = 15*[16^2] + 1*[16^1] + 10*[16^0] = 10 + 16 + 3840 = 3866
Для перевода BIN->DEC
следует работать со степенями двойки, например:
1011b =
1*[2^3] + 0*[2^2] + 1*[2^1] + 1*[2^0] = 1*1 + 1*2 + 0*4 +
1*8 = 8 + 0 + 2 + 1 = 11d
Перевод HEX<->BIN
производится
разбиением двоичного числа на тетрады (т.е. на группы по 4 цифры, т.к. 2^4 =
16) и переводом каждой тетрады в HEX-цифру.
Например:
011010101010b
= 0110 1010 1010 = 6AAh
==========================================================================
Q: А числа с запятой? Чему равно [1 / 1010]b = xb = yd ?
A: Также, как и целочисленные, т.е. с помощью степеней двойки, только
разряды "справа" от запятой будут соответствовать 1/2, 1/4, 1/8, 1/16 и т.д., т.е. отрицательным степеням двойки.
Например:
0.111b = ([1/2] + [1/4] + [1/8])d = 0.875d
Для
перевода числа в «обратную сторону» (т.е. из десятичной
в двойчную с.с.)
можно воспользоваться следующим алгоритмом (прислал
BobJohnson на
вопрос N 3622):
Целая часть переводится, как
обычно, а дробная следующим способом:
1.
Умножим ее на 2.
2. Если результат больше 1, то пишем 1 и вычитаем 1 из результата (т.е.
еще раз берем дробную часть), иначе - пишем 0.
3. Если исходная дробная часть после шага 2 не равна 0, то идем на шаг 1.
4. Конец алгоритма.
Таким образом, мы хотим 0.875 в двоичную С.С.:
0.875 * 2 = 1,75
пишем 1, остается 0,75
0.75 * 2 = 1,5
пишем 1, остается 0,5
0.5 * 2 = 1
пишем 1, остается 0
все. число получилось 0.111b
Теперь вторая часть вопроса: [1/1010]b=0.1d
Попробуем применить деление "в столбик":
10000 |1010
- 1010 +----
------ |0.0001100(1100)...
01100
- 1010
-----
10000 (приходим к
изначальному делимому
=> дробь имеет период)
-
...
Значит [1 / 1010]b = [0.0001100(1100)]b = 0.1d
Для
дальнейшего разбора вопроса попробуем представить частное
в виде суммы ряда степеней двойки, которым соответствует "единица" в
частном в двоичном представлении:
0.1d = [1/16] + [1/32] + [1/256] + [1/512] ...
И действительно:
+<><>
-------|
\ 3
0.1 = \ ----------
/
(2k+1)
/ 8 * 2
-------|
k=0
Здесь k пробегает все значения от нуля до бесконечности.
Для перевода HEX<->DEC
применяются
аналогичные методы, только вместо основания 2 применяется основание 16.
==========================================================================
Q: Как использовать прерывания в защищенном режиме? Как работать
с графикой\текстом из-под PM?
A: Стандартными
обработчиками прерываний, с которыми можно было работать в реальном режиме,
пользоваться нельзя, так что
надо писать собственные обработчики. Примеров в Сети очень много, поэтому
развивать здесь эту тему не имеет смысла.
Работать
с оборудованием можно посредством портов или прямой работой с памятью.
Например,
для вывода на экран текста пользоваться пользоваться сегментом видеобуфера (адреса
B800h:xxxxh). Вывод графики можно производить
одним из двух способов:
писать напрямую в видеобуфер (для разных режимов по-разному, начиная с A000h:0000h) или программировать
контроллер дисплея 6845 (об обоих способах можно почитать в книге Р.Журдена).
Программирование остальных устройств также производится с помощью портов (см.
след. вопрос) и перепрограммирования контроллера прерываний (см. Юрова
гл. 15 и 17).
Пример программы, работающей
с прерываниями в защ. режиме:
http://www.vcl.ru/html/cpu/80486/ch3.htm
==========================================================================
Q: Как программировать звуковую карту под ДОС? А мышь? НМЖД?...
A:
1.
Описание программирования Sound Blaster/Pro/16, Adlib.
http://www.dospage.by.ru/files/howtosb.zip
2. Для
работы с мышью под DOS обычно используются ф-ции прерывания int33h. Их
описание можно найти в списке Ральфа Брауна, в
книге С.Зубкова.
Подборку документов по теме
можно скачать:
http://kalaidjian.pochtamt.ru/mouse.rar
Также см. Библиотеку Системного Программиста
(Том 33)
http://shmelev.vistcom.ru/doc/bsp/fv33.zip
3. Про
программирование "жестких дисков":
http://www.dospage.by.ru/files/hdd_1.zip
http://kalaidjian.nm.ru/idedisk.rar
Библиотека Системного
Программиста (Том 1, книга 3, том 33)
http://stratum11.pstu.ac.ru/~leonid/base/fv01b.zip
http://shmelev.vistcom.ru/doc/bsp/fv33.zip
Также можно почитать
Журдена(гл 5.4)
Если доступны
прерывания, то можно пользоваться int13h, int25h/26h
4. Дисководы:
http://www.dospage.by.ru/files/fddprog.zip
5.
Клавиатура: используйте порты 60h и 61h. Подробно читайте:
Библиотека Системного
Программиста (Том 2, книги 1-2, Том 33)
http://stratum11.pstu.ac.ru/~leonid/base/fv02.zip
http://shmelev.vistcom.ru/doc/bsp/fv33.zip
6.
Видеоадаптеры:
Библиотека Системного Программиста (Том 3 и
Том 21)
http://stratum11.pstu.ac.ru/~leonid/base/fv03.zip
http://shmelev.vistcom.ru/doc/bsp/fv21.zip
7.
Прочее: Библиотека Системного Программиста (Том 33)
http://shmelev.vistcom.ru/doc/bsp/fv33.zip
==========================================================================
Q:
Киньте, плиз, исходники БИОСа.
A: Исходники BIOS'ов - штука
дорогая (обычно стоит не один десяток тыс. долларов), поэтому иметь исходники
имеет смысл только фирмам, разрабатывающим своё железо. Хотя в Интернете Вы
можете найти исходник BIOS для Intel 8088 или NEC "V20" материнских
плат:
http://www.dospage.by.ru/files/bios-asm.zip
Если
же Вам нужно работать с прошивкой, а не с ее исходником версией, то добро
пожаловать на
http://yusoft.kulichki.com/russian/doc/biosedit.htm
==========================================================================
Q: Где взять исходники прерываний BIOS\DOS?
A: Исходники прерываний DOS
можно найти в исходниках самого DOSа. Например, исходники
MS-DOS v3.3 можно скачать:
http://www.dospage.by.ru/files/dos33src.zip
Исходники
прерываний BIOS можно найти в в исходниках BIOS (см. соответствующий
вопрос).
Однако
это не лучший вариант, т.к. со временем (с выходом новых версий) код
обработчиков может меняться, поэтому попробуйте следующий вариант:
Предположим
Вам надо посмотреть подпрограмму, выполняющуюся при вызове ф-ции 02h прерывания
int 10h. Зайдем в Ваш любимый отладчик (здесь описаны действия для работы с
Debug.exe).
Посмотрим,
что у нас лежит в двойном слове по адресу 0000h:0040h (т.е.
по смещению 4*10h, мы ведь смотрим int10h, не так ли? Для каждого адреса(вектора)
отводится по 4 байта, потому-то мы и умножаем на 4):
-d 0000:0040
0000:0040 07 00 70 CC 4D F8 00 F0-41 F8 00 F0
Скорее
всего, у Вас будет 070070СС => обработчик сидит по адресу CC70h:0007h.
Теперь
смотрим, что "сидит" по этому адресу(дизассемблируем):
-U CC70:0007
CC70:0007 FB STI
CC70:0008 84E4 TEST AH,AH
CC70:000A 7414 JZ 0020
CC70:000C 3D024F CMP
AX,4F02
CC70:000F 740A JZ 001B
CC70:0011 80FC4F CMP
AH,4F
CC70:0014 740A JZ 0020
CC70:0016 EA0C00860E JMP
0E86:000C
Мда..
тут проверяются возможные варианты номеров ф-ции. Такой способ отладки не
очень-то приятен. Однако он может Вам пригодиться, если Вы хотите получить
целостное представление о коде BIOS.
Все
же, давайте попробуем по-другому. Попробуем протрассировать код:
-r cs
CS 15AA
:cc70
-r ip
IP 0100
:0007
Теперь
в паре CS:IP полный адрес нашего обработчика int 10h
-r AX
AX 0000
:0201
Подсунем
ему (обработчику) вызов ф-ции 02h(как и договаривались)
-t
AX=0201 BX=0000
CX=0000 DX=0000 SP=FFEE
BP=0000 SI=0000 DI=0000
DS=15AA ES=15AA SS=15AA
CS=CC70 IP=0008 NV UP EI PL NZ NA PO NC
CC70:0008 84E4 TEST AH,AH
Все!
Теперь мы в обработчике! Узнаёте первую строчку? (тут сначала идёт статус
регистров, а затем дизассемблированная команда). Далее, выполняя команду t, вы
будете гулять по обработчику, в том же порядке выполняя комады, как это бы
делалось в результате выполнения следующего кода:
mov ah, 02h
mov al, 01h
int 10h
Выход
из обработчика Вы обнаружите, увидев примерно такую строчку:
AX=0201 BX=0000
CX=0000 DX=0000 SP=FFEE
BP=0000 SI=0000 DI=0000
DS=15AA ES=15AA SS=15AA
CS=C000 IP=0226 NV UP EI NG NZ NA PO NC
C000:0226 CF IRET
Команда IRET - возврат из обработчика прерывания.
Таким
образом можно проследить "путь" в любом обработчике любого
прерывания.
==========================================================================
Q: Я взял код прошивки BIOS и дизассемблировал его.
Фигня получается.
A: Информация для размышления
- как Ваш дизассемблер отличает код от данных? Т.е. не мог ли он
"дизассемблировать" данные?
Представьте
также следующий вариант - есть такая вот программа:
====================
.model tiny
.code
org 100h
main:
a:
cli
jmp a
end main
====================
В
HEX-редакторе (например QView) она выглядит так:
FA EB FD
Дизассемблируем
её:
00000000: FA cli
00000001: EBFD (1) jmp 00000000
Пока
что всё правильно.
А
теперь попробуем вставить байт данных в самое начало программы, сохранив наш
код(при этом мы просто "перепрыгнем" через этот байт):
====================
.model tiny
.code
org 100h
main:
jmp a
OUR_BYTE db 1 ; вот он !
a:
cli
jmp a
end main
====================
В
HEX-редакторе читаем:
EB 02 90 01 FA EB FD
Дизассемблер
покажет следующее:
00000000: EB02 (1) jmp 00000004
00000002: 90 nop
00000003: 01FA add dx,di
00000005: EBFD (2) jmp 00000004
Ну
что, похоже на исходный вариант программы? Нет? А теперь представьте(для
примера), что у Вас в результате такого сдвига случайно попалась команда 0E.
Дизассемблер показал, что это push cs, а это может быть, например, кусок
команды B0 0E (т.е. mov al, 0eh). Такое "разделение" может быть
вызвано, упомянутым выше, сдвигом кода из-за данных.
Вывод:
дизассемблером НЕЛЬЗЯ получить
исходник прошивки, т.к. нельзя отличить код от данных. Если Вы хотите таки
получить небольшие участки ассемблерного кода, то используйте отладчики.
==========================================================================
Q: Что такое сопроцесcор. Как с ним работать?
A: Сопроцессор – это отдельная
микросхема, реализующая различные математические функции (в т.ч. и с плавающей
запятой) на _аппаратном_ уровне.
Подробно
о работе с математическим сопроцессором читайте в книге Зубкова или Юрова(гл.
19).
Далее
идет ответ из дружественного FAQ:
Вот коротенький пример.
--soproc.asm-------------------------------------
.model tiny
.code
.386 ; привычка :)
.387 ;
использование сопроца
.code
main:
finit ; инициализация сопроца
fild data1 ; загрузка data1
fiadd data2 ; складывание с data2
fist _result ; сохранение результата в
; _result
ret
data1 dw 1
data2 dw 200
_result dw ?
end main
-------------------------------------------------
Теперь немного теории.
Пример команды:
fild
^^^^
|||
|||
||*-- 'ld' - load, загрузка числа в стек сопроцессора
|*--- 'i' - integer, означает, что работаем с ЦЕЛЫМИ данными (
| еще варианты - '', то
есть fld, например - загрузка вещественного
| числа в сопроцессор,
'b', т.е. fbld - загрузка BCD числа)
*----
'f' - обозначает, что это команда сопроцессора
Примеры команд:
fld data1 ; загрузка
вещественного числа из памяти
;
по адресу data1 в сопроцессор
fist _result ; сохранение
числа как целого в память по
; адресу _result (при
необходимости оно
; округляется
- это делает сам сопроц)
fistp _result ; то же самое,
но при сохранении числа оно
;
выталкивается из стека сопроца
fsqrt ;
вычисление квадратного корня из st0, то
;
есть аргумент берется из стека, туда же и
;
помещается значение корня
Вообще, для понимания механизма работы возьмите Turbo Debugger:
(мы
отлаживаем не ту программу, что написана выше =)
F10/View/Numeric processor:
Здесь видно, что в стеке сопроца находится число 300 :)
+=[x]=80486
IPTR=54CE3 OPCODE=706 OPTR=54CEE==2=[][]=+
|Valid ST(0)
300 | im=1 | ie=0 |
|Empty
ST(1) | dm=1
| de=0 |
|Empty
ST(2) | zm=1
| ze=0 |
|Empty
ST(3) | om=1
| oe=0 |
|Empty
ST(4) | um=1
| ue=0 |
|Empty
ST(5) | pm=1
| pe=0 |
|Empty
ST(6) |iem=0
| ir=0 |
|Empty
ST(7) | pc=3
| cc=0 |
| | rc=0
| st=7 |
| | ic=0 | |
+xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+======+=====-+
Выполняем:
cs:0107 D9FA fsqrt
+=[x]=80486
IPTR=54CE7 OPCODE=1FA OPTR=54BE0==2=[][]=+
|Valid ST(0)
17.320508075688773 | im=1 | ie=0
|
|Empty ST(1) | dm=1 | de=0 |
|Empty
ST(2) | zm=1
| ze=0 |
|Empty
ST(3) | om=1
| oe=0 |
|Empty
ST(4) | um=1
| ue=0 |
|Empty
ST(5) | pm=1 | pe=1 |
|Empty
ST(6) |iem=0
| ir=0 |
|Empty
ST(7) | pc=3
| cc=0 |
| | rc=0
| st=7 |
| | ic=0
| |
+xXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+======+=====-+
Получили вещественное число в стеке сопроцессора. Сохраним его в памяти
по адресу ds:[110] как целое:
cs:0109 DF1E1001 fistp word ptr[0110]
Смотрим содержимое
сегмента данных:
ds:0110 11 00 FF 16 57 9A A5 1B
^^^^^ вон он наш результат
:)
==========================================================================
Q: Как работать с ф-циями Sin/Cos/Tg/Ln/ArcSin и пр. ?
A:
самый
простой способ – использовать сопроцессор:
fcos, fsin, ; Вычисление Sin/Cos угла,
; находящегося в стеке сопроцессора.
; Угол должен быть задан в радианах.
; Результат сохраняется в верхине стека
; сопроцессора
– регистре st(0)
; команда
не имеет операндов.
fsincos ;
одновременно вычисляет и Sin и Cos, в
;
st(0) помещается Sin, в st(1) – Cos
fratan ; вычисление _частичного_ арктангенса
угла,
;
находящегося в вершине стека сопроцессора
fyl2x
; ST(0) = ST(1)*log2(ST(0))
fyl2xp1 ;
ST(0) = ST(1)*log2(ST(0)+1)
Таких
команд как Arcsin, Arccos, ArcCtg в арсенале сопроцессора
нет, однако значения этих ф-ций можно получить самому по формулам:
arcsin(a) = arctg(a/sqrt(1-a*a))
arccos(a) = 2 *
arctg(sqrt(1-a)/sqrt(1+a))
arcctg(a) = arctg(1/a)
Подробно, с примерами и
руководством к работе следует почитать у В.Юрова
Другой
способ - наиболее быстрый (если значения триг. ф-ций надо считать постоянно):
построение таблицы значений Sin\Cos для различных аргументов с заданным шагом и
дальнейшая выборка нужных значений. Построение этой таблицы может производиться
как с помощью ф-ций сопроцессора, так и с помощью одного из след. способов:
a) Ряд Маклорена (частный случай ряда Тейлора):
В общем виде ряд Маклорена
выглядит следующим образом:
f[x]
= f[0] + f'[0]*x/1! + f''[0]*x^2/2! + … + f(n)[0]*x^n/n! + …
Здесь f(n)[x] -
производная f[x] n-го порядка,
"^" - знак
степени: 2^3 = 2*2*2 = 8.
"!" - знак факториала. Y! = 1*2*3*4*...*Y (0! = 1)
В частности sin[x],
cos[x], arcsin[x], arctg[x] можно разложить в ряд Макларена след. образом:
sin[x] = x - ([x^3] /3!) + ([x^5]
/5!) - ([x^7] /7!) + ([x^9] /9!) - ... +
+ ([(-1)^(n+1)] *[ x^(2n-1)] /
[2n - 1]!) + …
cos[x] = 1 - ([x^2]
/2!) + ([x^4] /4!) - ([x^6] /6!) + ([x^8]
/8!) - ... +
+ ([(-1)^n] *[ x^(2n)] / [2n]!)
arcsin[x] = x + ([1 * x^3] / [2*3]) +
([1*3]*[x^5/5]/[2*4]) + ([1*3*5]*[x^7/7]/[2*4*6]) + …
arctg[x] = x - [x^3/3] + [x^5/5] - [x^7/7] + …
b) Рекуррентная формула:
cos(X_n) = 2*cos(X_{n-1}) * Step - X_{n-2}
Соответственно, X_0=1, X_1=Step (т.е. шаг).
Пример
программы, строящей таблицу косинусов по этой формуле представлен
ниже:
--zedronts.asm-----------------------------------
.model
tiny
.data
Num_Cosines
equ 720 ;
Число ячеек
Step
equ 0FFFDh ;
cos(360/Num_Cosines)*2^16
; Таблица косинусов в формате 16.16 с фиксированной точкой
Costable
dw 0FFFFh, Step, Num_Cosines-2 dup(?)
End_table
label
.code
.386
org
100h
start:
mov di,offset Costable[2*2] ; Начинаем с X_3
mov ecx,Step
loop_1:
xor ebx,ebx ; EBX = 0
xor eax,eax ; EAX = 0
mov bx,[di-2*2] ; bx=X_{k-2}
mov ax,[di-2*1] ; ax=X_{k-1}
imul ecx ; EDX:EAX=cos(X_{k-1})*Step
shrd eax,edx,15 ; EAX=2*cos(X_{k-1})*Step
sub eax,ebx ; EAX=2*cos(X_{k-1})*Step
- X_{k-2}
mov [di],ax ; Сохраним полученное значение
add di,2 ; k=k+1
cmp di,offset End_table
jb loop_1
ret
end
start
-------------------------------------------------
Для вычисления Sin воспользуйтесь основным тригонометрическим
тождеством, учитывая четверть в которой находится угол.
с) Для подсчёта обратных триг. ф-ций можно применять рекурсивный алгоритм с
применением метода Ньютона(программа для упрощения написана на Паскале):
--arcsin.pas-------------------------------------
function arcsin(x, fi: REAL): REAL; {результат - угол в рад.}
begin
if ABS(Sin(fi)-x)>0.0000001 {задаём точность}
then arcsin:=arcsin(x,fi+(x-Sin(fi))/Cos(fi)) else arcsin:=fi;
end;
begin
Writeln((Arcsin(Sqrt(3)/2,0) * 180/pi):9:9);
end.
-------------------------------------------------
==========================================================================
Q: Как убрать «моргание» изображения при работе с графикой ?
A: Моргание имеет место из-за
того, что различные элементы большой картинки заканчивают отрисовку в различные
моменты времени. Если картинка постоянно обновляется, то «время жизни»
различных компонентов также различно, поэтому появляется впечатление, что
картинка «моргает». Чтобы избежать этого эффекта картинку следует выдать
полностью в один момент времени, предварительно отрисовав ее в
отдельной области памяти (видеостраницы в ДОС) или в виде растровой картинки(в
Win32).
Пример
работы с видеостраницами под ДОС:
--pages.asm--------------------------------------
.model small
.code
main:
mov ax, 12h ;Устанавливаем граф. режим
int 10h
mov ah, 05h ;Текущая видеостраница - первая
mov al, 01h
int 10h
mov cx, 300 ;Здесь мы рисуем линию в цикле
mainloop: ;Координаты (X;Y) = (CX;DX)
mov ah, 0Ch
mov bh, 02h ;Рисуем во вторую видеостраницу...
mov al, 02h ;...зеленым цветом
mov dx, 200
int 10h ;Поставить точку
loop mainloop
xor ah, ah ;Ждем, пока пользователь нажмет на
int 16h ;какую-нибудь клавишу
mov ah, 05h ;Установим текущей видеостраницей вторую.
mov al, 02h ;ПОКАЗАТЬ КАРТИНКУ !
int 10h
xor ah, ah ;Ждем, пока пользователь нажмет на
int 16h ;какую-нибудь клавишу
mov ax, 03h ;Установка текстового режима
int 10h
mov ah, 4ch ;Выход и возврат управления ОС
int 21h
end main
-------------------------------------------------
==========================================================================
Q: Как сделать так, чтобы не работали одновременно 2
копии моей
программы?
A: Пример
для MASM32:
--findwind.asm-----------------------------------
.386
.model
flat, stdcall
option
casemap:none
include
\masm32\include\windows.inc
include
\masm32\include\user32.inc
include
\masm32\include\kernel32.inc
includelib
\masm32\lib\user32.lib
includelib
\masm32\lib\kernel32.lib
.data
ProgName
db "My prog",0
.code
_start:
;
ищем окно нашей программы
invoke
FindWindow,0,addr ProgName
;
если находим, то выходим
test
eax, eax
jnz
quit
;
здесь основной код, выполняющийся при запуске первой копии:
invoke
MessageBox, 0, offset ProgName, offset ProgName, 0
quit:
invoke ExitProcess,0
end
_start
-------------------------------------------------
==========================================================================
Q:
Как выдвинуть лоток cd-rom'а
A: Если под ДОС, то читайте
соответствующий документ по ATAPI-пакетам: http://www.dospage.by.ru/files/atapi-cd.rar
Под Win32
по-проще(использовался MASM32):
--cdcool.asm-------------------------------------
.386
.model flat, stdcall
option casemap:none
include
\masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\winmm.lib
include
\masm32\include\winmm.inc
.const
OPEN DB 'Set CDAudio Door Open Wait',0
CLOSE DB 'Set CDAudio Door Closed Wait',0
.code
_start:
mov EBX, 0 ;0
для ф-ций
push EBX
push EBX
push EBX
push OFFSET OPEN ;для
открытия
;push OFFSET CLOSE ;для
закрытия
call mciSendStringA
push EBX
call ExitProcess
;Выход
end _start
-------------------------------------------------
==========================================================================
Q: Как под Win32 работать с портами/памятью?
A:
Возможно
несколько вариантов:
1. Если порт стандартный (COM, например), то можно с ним работать как с файлом с помощью функций CreateFile, ReadFile, WriteFile (описание см. в MSDN). Если
порт нестандартный, то это способ не сработает.
2. Перейти на нулевое кольцо
защиты (как это делают вирусы) и работать с портами напрямую, как из-под ДОС. Уровень Ring-0 -
уровень
Бога.
3. Написать драйвер, который
как раз работает на уровне ядра и может работать напрямую с памятью\портами и использовать его функции из своей программы, которая может быть написана не
только на ассемблере, но и на ЯВУ(так в основном делается для программирования
под WinNT)
Проект написания wdm-драйвера для LPT c
комментариями можно найти на
http://progrex.narod.ru
4. Можно воспользоваться уже
готовыми библиотеками, например NTPort Library http://www.zealsoftstudio.com/
В пакете прилагаются примеры на различных
языках программирования.
Вот еще пара ссылок по теме:
http://www.entechtaiwan.com/tools.htm
==========================================================================
Q: Как написать свой драйвер под Win32?
A: В первую очередь необходимо
скачать стандартный набор программ, документации и библиотек для создания
драйверов, предоставляемый Microsoft - DDK (Drivers Development Kit) для той платформы, под которую
Вы собираетесь написать драйвер.
1. Для Win98:
http://download.microsoft.com/download/win98SE/Install/Gold/W98/EN-US/98DDK.EXE
Или
здесь:
ftp://shelek.no-ip.com/ddk/98ddk.exe
2. Для WinME
ftp://shelek.no-ip.com/ddk/Wme_DDK.exe
3. Для WinNT4 (все
сервиспаки)
ftp://shelek.no-ip.com/ddk/nt4ddk.zip
4. Образ диска для DDK Для
WinXP:
http://windriver.ssarang.net/pds/DDK_XP.ISO
Или
здесь:
ftp://shelek.no-ip.com/ddk/Ddk_xp.iso
5. Для Win2000
ftp://shelek.no-ip.com/ddk/2kddknly.exe
Хотя
всё это можно купить на радиорынке...
Полезно
также вооружиться отладчиком, например SoftIce. Также полезно иметь под рукой
MSDN.
А далее вперед -
компилировать примеры из DDK, смотреть описания в MSDN и пр.
Чтобы написать что-нибудь
свое, достаточно перекроить один из примеров к DDK.
Следует
уточнить, что в Win32 применяются различные варианты драйверов, напрмер VxD (Virtual Device Driver), WDM (win32 driver model) и пр., поэтому
при выборе документации следует учитывать неоднозначность понятия
"драйвер".
Итак. Если Вы хотите почитать подробно и доступно о написании
драйверов, то можно посоветовать следующие источники:
1. Цикл статей "Как писать драйвера", "Драйвер с
нуля" и другие статьи по теме:
http://www.shelek.com/club/view.php?id=52&type=0
2. Простое руководство от Bob Johnson, как,
пользуясь MASM написать самому VxD-драйвер под Windows 9x (на примере
антивируса):
http://www.bobjohnson.nm.ru/files/driver.zip
3.
Гречко
Ю.Б "Пишем драйвер WDM на Ассемблере"
http://progrex.narod.ru/asmdrv.html
исходники к статье
http://progrex.narod.ru/files/AsmDrv.zip
4. Туториалы
Iczelion'a "Уроки VxD" (подробно на русском
языке):
http://www.wasm.ru/publist.php?list=3
Из
"бумажных"
книг на русском можно упомянуть следующие:
1.
Свен Шрайбер «Недокументированные возможности Windows 2000». Издательство
«Питер» 2002 год.
2.
П. И. Рудаков, К. Г. Финогенов «Язык ассемблера: уроки программирования»
Диалог
МИФИ 2001 год
3.
Светлана Сорокина, Андрей Тихонов, Андрей Щербаков «Программирование драйверов
и систем безопасности». Издательство «БХВ-Петербург» 2002 год
Из
английского:
1.
Программирование
WDM (Walter Oney)
http://www.shelek.com/club/download.php?id=9
и
приложения к ней
http://www.shelek.com/club/download.php?id=13
2.
Windows 2000 device driver book Art Baker Jerry Loza
http://www.shelek.com/club/download.php?id=10
3.
Writing Windows VxDs & Device Drivers; Programming Secrets for Virtual
Device Drivers, автор Karen Hazzah
==========================================================================
Q: Что такое «кольца защиты» и зачем они нужны?
A: Кольца
защиты, то же
что и уровни привелегий.
---------------------------------------------------------------
Ответ
на вопрос 3266. Отвечает Knignick:
Уровни
привилегий - механизм защиты программ друг от друга в защищенном режиме. В
дескрипторе каждого сегмента в защ.режиме указывается какой уровень (ring) ему
соотвествует.
Минимальные привелегии соотвествуют
прикладным прогам (ring 3).
Ядро
ОС функционирует на уровне 0.
Защита
основана на аппаратном сравнении уровня текущего выполняемого сегмента с
уровнями тех сегментов, к которым он обращается. А слово ring идет от их
традиционного графического изображения в виде концентрических колец,
которое в принципе отражает следующую идею: все привилегии внешнего кольца
доступны следующему вглубь.
---------------------------------------------------------------
Про защищенный режим можно
прочитать в любой книге по ассмеблеру.
Если же Вы захотите подробно
изучить его, то прочитайте цикл статей от
Broken Sword
"Процессор INTEL в
защищенном режиме"
или
http://www.wasm.ru/publist.php?list=24
Уровни привелегий, в
частности, рассматриваются в 13-ом выпуске:
http://www.wasm.ru/print.php?article=pipm13
==========================================================================
Q: Как мне корректно подсесть на Ring-0?
A:
Подробно
можно почитать на сайте
http://z0mbie.host.sk в разделе Ring-0, на
http://www.wasm.ru в разделе "вирусология", а также можно исследовать исходники вируса "Чернобыль"
http://kalaidjian.w6.ru/vir/cih.rar
Здесь же приведем программу, работающую под Win9x и переходящую в
Ring-0 посредством изменения дескрипторной таблицы
прерываний:
--ring0.asm--------------------------------------
.386P
.MODEL FLAT, STDCALL ;Плоская модель памяти
option casemap:none
include
\masm32\include\windows.inc
include
\masm32\include\kernel32.inc
includelib
\masm32\lib\kernel32.lib
.DATA
lpOldGate dd 0 ;Место
для старого шлюза
IDT db 6 dup (0) ;Место для дескрипторной
таблицы
ExceptionUsed EQU 5 ;Номер исключения
.CODE
start:
sidt fword ptr IDT ;Получить IDT
mov ebx, dword ptr
[IDT+2] ; ebx -> IDT
add ebx, 8*ExceptionUsed ; ebx -> IDT запись ExceptionUsed
cli ;Запретить прерывания
mov dx, word ptr [ebx+6] ;Сохраним старый шлюз: старшее
слово
shl edx, 16d
mov dx, word ptr [ebx] ;Младшее слово
mov [lpOldGate], edx
mov eax, offset
Ring0Code ;"поставить
ловушку(хук)"
; - новый шлюз
mov word ptr [ebx], ax ;Младшее слово
shr eax, 16d
mov word ptr [ebx+6], ax ;Старшее слово
int ExceptionUsed ;Вызываем исключение
mov ebx, dword ptr
[IDT+2] ;Восстанавливаем шлюз
add ebx, 8*ExceptionUsed
mov edx, [lpOldGate]
mov word ptr [ebx], dx
shr edx, 16d
mov word ptr [ebx+6], dx
invoke ExitProcess,
-1 ;Выход
Ring0Code PROC
mov eax, cr0
;Вставьте сюда ваш код, ибо мы под Ring0 =)
iretd
Ring0Code ENDP
end start
-------------------------------------------------
==========================================================================
Q: Как програмировать под Linux на ассемблере?
A:
==========================================================================
Q: Как заставить мой комп(или модем) работать быстрее?
A: Однозначного ответа на этот вопрос дать нельзя, т.к.
для разного набора оборудования эти советы различны, однако существует некоторый
набор общих советов на эту тему, в том числе и «народные». Их можно найти в
списках проектов
на http://kalaidjian.nm.ru .
Автор проекта лишь выдает список советов, однако не отвечает за их актуальность и
работоспособность.
==========================================================================
Q: Как «ломать» программы ?
A: Научиться "ломать"
программы можно
только ломая их. В основном это - кропотливая работа с дизассемблером и
отладчиком. Без опыта программирования на ассмеблере - никуда. Желательно также
иметь опыт программирования на машинном языке.
Для
того, чтобы осмотреться, можно почитать некоторые
статьи(всё про
Win, т.к. это наиболее просто):
1. "Как ломать программы Windows" (C) ED!SON [UCF], перевод
Mr.Boco/TCP
http://kalaidjian.nm.ru/Lomka.rar
2. Распространенный FAQ по взлому для новичков:
http://xaker.online.kg/stat'i/diff/Xak_prog.htm
3. "Учебник по взлому windows-приложений"
http://olegk99.chat.ru/hack8.htm
4. Взлом с WinDASM
http://www.madalf.ru/cracks/cracks3.shtm
5. 15 подробно
разобранных взломов с кратким руководством по SoftICE:
http://kalaidjian.nm.ru/crttut.zip
Информация по-серьезнее:
1. Группа статей
"Исследование программ"
http://www.wasm.ru/publist.php?list=3
2. Крис Касперски. "Дизассемблирование в уме".
http://kalaidjian.nm.ru/head.rar
3. Крис Касперски "Образ мышления IDA" http://www.bobjohnson.nm.ru/files/IDA.rar
Если
Вы немного поднабрались опыта, то добро пожаловать на
http://www.reverser-course.de/
Тут
Вы сможете зарегистрироваться и непрерывно обучаться на взломе различных
небольших программ.
==========================================================================
Q: Что такое RTFM, IMHO, AFAIK и другие слова, столь часто
употребляемые экспертами RusFAQ.ru?
A: Это некоторые жаргонные и
часто удобные словечки:
IMHO (=ИМХО) - In My Humble Opinion. Одно
из наиболее употpебительных слов в Фидо и Usenet. Давно потеpяло пеpвоначальное значение, чаще всего употpебляется
пpосто
в значении "по-моему" или, в кpайнем случае,
"мне кажется". В то же вpемя обязательно
употpебление этого слова пpи явно споpных заявлениях. Пpизнаком
кpайнего занудства считается выделение IMHO запятыми.
RTFM
- Read The
FUCKING Manual. Втоpое по употpебительности после IMHO выpажение. Означает: "Пpежде чем
спpашивать, пpочитайте pуководство по использованию". Сокpащение почти
утpатило пеpвоначальный оттенок гpубости.
AFAIK
(=АФИК=НЯЗ) – As Far As I Know, т.е. «насколько я знаю»
AFAIR
(=АФИP=НЯП) – As Far As I Remember, т.е. «насколько я помню»
ЯВУ – сокращение от «Языки Высокого Уровня»
==========================================================================
Q: Что такое “станция BBS"?
A: Станция ББС - это, грубо
говоря, склад файлов, к которому можно получить доступ через
псевдографический или текстовый интерфейс, позвонив на телефонный номер модемом и
скачав то, что нужно... Ничего сложного. Для доступа не нужно иметь
специальных программ - HyperTerminal прилагается к стандартному пакету Windows.
В своё время станции носили более
универсальный характер - это и склад файлов, и почтовый ящик и
выход в ФИДО без регистрации и прочее, но сейчас эти дополнительные
возможности мало кому нужны из-за существования Интернет...
Однако многие файлы, которые лежать на
станциях нельзя найти в Интернет + связь не оплачивается в пределах города, поэтому
ббски существую и по сей день, хотя и быстро вымирают (за последние несколько лет
произошло повальное вымирание, и даже не известно выпускаются ли AMBL или NBL ББС-листы).
В Москве существуют по крайней мере 2 станции,
базирующиеся на документации по ассемблеру. Причём они содержат некоторые
программы и документы, которые Вы не найдете в Интернете. Одна из них - TiCOiN
BBS. Для получения к ней доступа (в пределах города, т.к. вне города Вам
придется оплачивать междугородную связь) достаточно связаться с Системным
Оператором(СисОпом) станции (kalaidjian@pochtamt.ru) и договориться о времени
подключения. СисОп также расскажет о том, как надо подключаться и выдаст
правила
подключения, скачки\закачки и пр.
==========================================================================
Q: Кто и зачем до сих пор использует DOS. Какой
смысл сейчас
писать что-то для него?
A:
1. Под ДОС программировать во многом проще.
Структура работы логична и
понятна, исходники открыты. Для новичков – это лучший полигон для работы.
2. По привычке. Многие начинали программировать, когда
еще не было W98/95 и
прочего.
3. Маленький размер и быстрая работа откомпилированных
программ. Маленький
размер исходников.
4. Возможность пощупать код на низком
уровне, дабы лучше
разобраться в работе программы,
а не строить её из «кубиков», как часто это делается в
Delphi\Buider, после чего непонятно с чем связана та или иная ошибка
5. Не все машины еще имеют на борту Win\Linux, поэтому
не стоит пока
хоронить ДОС ИМХО...
У MTU-INFORM на
http://support.mtu.ru был опрос (где-то в 1999г), по теме "ДОС мёртв?". Так вот:
около 95% ответили НЕТ.
6. Дополнительное подтверждение того, что ДОС жив, Вы можете найти
на
http://www.dospage.by.ru , а также на
http://int21.narod.ru/links/
Посетителей
первого сайта к времени создания данного FAQ было уже больше 9500. Значит это
еще нужно людям! А если это нужно людям, то и нужны программы под эту ОС.
==========================================================================
В создании FAQ принимали участие:
Tigran Kalaidjian kalaidjian@pochtamt.ru 2:5020/2987.25
Hangatyr hangatyr@centrum.cz
Zedr0n gamesru@narod.ru
Eugene
Ivanov Eugene_Ivanov@mail.nnov.ru
Конструктивная критика и замечания:
Bob Johnson BobJohn@NewMail.ru
Blackman blackman@ezmail.ru
Подборка вопросов составлена
на основе архивов RusFAQ.ru
При
нахождении мертвых ссылок просьба писать на kalaidjian@pochtamt.ru
Данный документ может быть выложен на любой сайт участниками проекта RusFAQ.ru