16.11.2007, 09:53
общий
это ответ
Здравствуйте, Masada!
Ответ на вопрос 1. $ - счетчик текущего адреса, показывает смещение от начала сегмента до самого знака $. Пример:
data segment
metka1=$ ; metka1=0, так как от начала сегмента до $ (metka1) ноль байт
mes1 db ‘abcd’
metka2=$ ; metka2=4, так как от начала сегмента до $ (metka2) четыре байта
mes2 db ‘12345’
metka3=$-mes2 ; metka3=9-4=5, так как от начала сегмента до $ (metka3) девять байт (4 байта это mes2 и 5 байтов это mes3) смещение mes3 в сегменте data составляет 4, поэтому metka3 имеет значение 5 (сам знак $ в сегменте имеет нулевую длину, только не путать с ‘$’ – это 1 байт).
Аналогично $ работает и в сегменте команд (определяет длину программы от начало сегмента команд до знака $).
Строка mov cx,offset Finish-100h, эту строку можно было записать так mov cx, Finish-100h, где Finish equ $.
В этих двух случаях в cx заносится длина кода (в байтах) программы до Finish.
Ответ на вопрос 2. Строка mov si,100h определяет начало программного кода в сегменте CS, но так как вирус пишется в COM исполнении, то все сегменты cs, ds, ss, es имеют один и тот же адрес (директива assume), а то что код начинается с адреса 100h это требование COM – формата.
Адрес DS:DX – нужен для реализации например функции 09h прерывания 21h.
Далее в программе есть строка
mov es, Seg_move ;где Seg_move dw 0bf00h
mov di, 100h
эти строки необходимы для адреса приемника ES:DI
строка
rep movsb
это строковая операция которая копирует бай находящейся по адресу DS:SI (это код программы) в область памяти расположенной по адресу ES:DI, rep число повторений (число раз копирований) определяет регистр cx.
Ответ на вопрос 3. При выполнении команды jmp dword ptr cs:[Off_move], будет сформирован адрес состоящий из двух слов. Первое слово (младшее) будет считано по адресу cs:[Off_move], второе (старшее) слово будет считано по адресу cs:[Seg_move], и будет совершен межсегментный переход.
При выполнение команды jmp dword ptr cs:[offset Lab_jmp] будет сформирован адрес перехода на метку Lab_jmp, так как явно указываем текущей сегмент и адрес метки в этом сегменте. Компоновщик компонуя программу вычислит длину адреса, а она окажется меньше 64K поэтому он заменит код перехода на короткий или внутрисегментный. Поэтому команда jmp dword ptr cs:[offset Lab_jmp] равносильно команде jmp Lab_jmp.
Удачи