Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Уроки ассемблеру. Быстро и просто. Урок 16


До сих пор мы баловались с вами, друзья, изменением текстовых файлов. Давайте побалуемся модификацией com-файлов. А именно - будем дописывать в начало нашего знаменитого файла hello.com некоторое количество байт - например, ничего не делающих операторов NOP. Только чур - изменённая программа hello.com должна работать, как и раньше!

За основу возьмём программу из 11-го урока.

;Всё, что следует за значком ";" - это комментарий.

.286 ;Разрешает ассемблирование непривилегированных инструкций
;процессора 80286 (реальный режим) и инструкций арифметического
;сопроцессора 80287.

CSEG segment ;Даём имя сегменту, а точнее определяем абсолютный
;сегмент в памяти программ по определённому адресу.
;Имя нашего сегмента будет CSEG.

assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG ;Задаём сегментные регистры, которые будем использовать для
;вычисления действующего адреса для всех меток и переменных, опре-
;делённых для сегмента или группы сегментов с указанным именем.
;У нас их четыре, - CS, DS, ES, SS и они будут указывать на наш
;единственный сегмент (мы его назвали CSEG).

org 100h ;Устанавливаем счётчик инструкций в текущем сегменте в соот-
;ветствии с адресом, задаваемым "выражением".
;Сейчас этот счётчик равен 100h - используется для всех программ
;типа .com

begin: ;Метка начала программы.


;Данная программа будет обновлять файл
;hello.com.

mov ax,3D02h ;Первоначально откроем файл для чтения-записи.
mov dx,offset File_name
int 21h
jc Message_bad

mov Handle,ax ;Если файл существует, сохраняем номер файла.
mov bx,ax

mov ah,3Fh ;Чтение в память.
mov cx,19h ;Определяем количество читаемых байт (напр.25 - больше нам пока не нужно).
mov dx,offset Finish ;по адресу памяти за нашей программой.
add dx,16 ;Добавляем х байт (наши nop и изменение DS).
int 21h
;В стеке - число реально прочитанных байт.
push ax


mov si,offset Add_nop ;Переносим х байт c адреса смещения Add_nop
mov di,offset Finish ;в конец нашей программы, но перед загруженной нами.
mov cx,16 ;Перемещаем 16 байт.
rep movsb

mov dx,0h ;Устанавливаем указатель с начала файла +0h.
mov cx,0h ;+0h мы указали потому, что будем
mov ax,4200h ;перезаписывать файл hello.com с первого байта.
int 21h ;

mov ah,40h ;Записываем программу (в т.ч.$) из смещения Finish
mov dx,offset Finish ;по адресу, указанному выше.
pop cx ;В cx - длина считанной нами программы.
add cx,16 ;Увеличиваем до длины, установленной нами.
int 21h

Message_ok: ;Подпрограмма успешного вывода строки и выхода.
mov bx,Handle ;Сначала сохраним файл, восстановив bx.
mov ah,3Eh ;Закроем файл.
int 21h

mov ah,9 ;Выводим строку.
mov dx,offset Mess_ok
int 21h
int 20h

Message_bad: ;Подпрограмма вывода сообщения об ошибке и выхода.
mov ah,9
mov dx,offset Mess_bad
int 21h
int 20h

Add_nop: ;Приписываемые байты (16 - посчитайте отладчиком).
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
mov ax,ds ;Изменяем ds в новой программе. Прямые операции с ds запрещены!
add ax,1 ;Внимание - вопрос! Почему изменяем ds на 1?
mov ds,ax
NOP ;Контрольный NOP. Проще смотреть в отладчике.


File_name db 'hello.com',0,'!$' ;Имя файла.

Mess_ok db 'Файл обновлён. Всем спасибо.$' ;Успешное сообщение и сообщение об ошибке (ниже).

Mess_bad db 'Файл не найден. Поместите hello.com в каталог с программой.$'

Handle dw 0FFFFh ;Определяем переменную (для идентификатора файла).

Finish equ $ ;Метка конца нашей программы!

CSEG ends
end begin

И конечно же, ml test.asm /AT (не забывая при этом устанавливать в текстовом файле кодировку 866).
Не забываем помещать файл hello.com в каталог с нашей программой.

На что следует обратить внимание? Нижеследующий текст и есть то, что мы приписываем в начало нашего файла hello.com:

Add_nop:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
mov ax,ds
add ax,1
mov ds,ax
NOP

На NOP'ы мы внимания не обращаем, а вот модификация регистра DS уже в программе hello.com должна нас заинтересовать. Как мы помним, текст выводимой строки "Hello, world" располагается по адресу DS:DX... Но почему мы увеличиваем DS всего лишь на единицу? Продолжим изучение материала в следующем уроке.

В избранное