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

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


А не пора ли нам, друзья, замахнуться на что-либо более серьёзное? Я имею в виду запись в файл. Впрочем, это вы сможете сделать уже и без меня. Спрашиваете как? Очень просто. Откроем наш файл HELP.EXE:



Перед началом всех действий нам нужно открыть файл.

HELP.EXE -> Указатель функций DOS/BIOS -> Функции DOS -> 3Dh Open file
Итак, мы видим входные значения - те данные, которые надо загрузить в соответствующие регистры:
— 3Dh - в регистр AH, а режим открытия в регистр AL;
— адрес буфера, содержащего записываемые данные - в DS:DX (так как у нас сегмент на самом деле один, то просто DX).

Затем нам нужно туда что-нибудь записать.

HELP.EXE -> Указатель функций DOS/BIOS -> Функции DOS -> 40h Write file
Далее, мы видим входные значения:
— 40h — в регистр AX;
— описатель файла — в регистр BX;
— адрес буфера, содержащего записываемые данные — в DS:DX (т.е. DX);
— число записываемых байт — в CX.

В какое место записывать?

Читаем ниже приписку о том, что нужно воспользоваться функцией 42h, чтобы установить указатель файла (куда, собственно будем писать — в начало, конец и т.д.).
HELP.EXE -> Указатель функций DOS/BIOS -> Функции DOS -> 42h Lseek file
Необходимо обратить внимание на значения регистров cx и dx, указывающих нам место записи.

И конечно, нам надо закрыть файл. HELP.EXE -> Указатель функций DOS/BIOS -> Функции DOS -> 3Eh Close file
Здесь всё просто, однако нужно не забыть записать в bx идентификатор открытого файла, полученного при открытии.

Создадим пустой файл 1.txt в каталоге с программой (Far это делает посредством Shift-F4 (имя файла) -> F2, выход). Проверим, чтобы он был равен 0 байт. Затем — файл test.asm в кодировке 866:

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.

mov ax,3D02h ;Загружаем в регистр ah число 3Dh (функция открытия
;файла с записью), а в al число 02h (пишем в конец).
;Можно было записать и так - mov ah,3Dh
;mov al,02h
mov dx,offset File_name ;Указываем имя файла в смещении по адресу File_name.
int 21h ;Выполняем функцию.

mov Handle,ax ;При открытии файлу будет присвоен номер, его и
;сохраняем для дальнейших действий,
mov bx,ax ;а заодно и сохраняем его в bx.

mov ax,4202h ;Используем функцию установки указателя.
;al=02h - устанавливаем в конец.
mov cx,0 ;Нам надо записать прямо в конец файла, поэтому
mov dx,0 ;обнулим cx и dx (иначе будет писать далее на
;значение (CX * 65536) + DX)
int 21h ;Выполняем функцию.

mov ah,40h ;Используем функцию записи в файл.
mov dx,offset one ;В dx занесём адрес смещения к записываемому
;тексту.
mov cx,1 ;Число записываемых байт - 1.
int 21h ;Выполняем функцию.

mov ah,3Eh ;Используем функцию закрытия файла.
mov bx,Handle ;Для закрытия обязательно "вспоминаем" его номер,
;номер у нас был сохранён в Handle.
int 21h ;Выполняем функцию.

mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset Vse_ok ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.


int 20h ;Выходим в DOS.

File_name db '1.txt',0,'!$' ;Определяем переменную File_name (доступную побайтно),
;с именем файла. Путь к файлу не указан, это значит,
;что файл находится в текущем каталоге.
Handle dw 0 ;Определяем переменную Handle, которую используем для
;хранения номера файла. Первоначально она будет равна 0.

one db '1' ;Определяем переменную one, содержащую символ "1",
;которую мы будем приписывать в конец файла.

Vse_ok db 'Успешно!$' ;Определяем переменную Vse_ok, доступную побайтно, с фразой
;"Успешно!". В одинарных кавычках, после знака "!" ставим
;знак "$".

;Завершение программы.
CSEG ends
end begin

Делаем так: ml test.asm /AT
Имейте в виду, пока мы не проверяем наличие в каталоге файла 1.txt, поэтому проследите за этим сами.
Текст программы, отслеживающей отсутствие файла:

.286
CSEG segment
assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG
org 100h
begin:
;Всё написанное выше пока опускаем.

mov ax,3D02h ;Загружаем в регистр ah число 3Dh (функция открытия
;файла с записью), а в al число 02h (пишем в конец).
;Можно было записать и так - mov ah,3Dh
;mov al,02h
mov dx,offset File_name ;Указываем имя файла в смещении по адресу File_name.
int 21h ;Выполняем функцию.

jc Error_file_metka ;Не удалось открыть файл. Прыгаем на метку.

mov Handle,ax ;При открытии файлу будет присвоен номер, его и
;сохраняем для дальнейших действий,
mov bx,ax ;а заодно и сохраняем его в bx.

mov ax,4202h ;Используем функцию установки указателя.
;al=02h - устанавливаем в конец.
mov cx,0 ;Нам надо записать прямо в конец файла, поэтому
mov dx,0 ;обнулим cx и dx (иначе будет писать далее на
;значение (CX * 65536) + DX
int 21h ;Выполняем функцию.

mov ah,40h ;Используем функцию записи в файл.
mov dx,offset one ;В dx занесём адрес смещения к записываемому
;тексту.
mov cx,1 ;Число записываемых байт - 1.
int 21h ;Выполняем функцию.

mov ah,3Eh ;Используем функцию закрытия файла.
mov bx,Handle ;Для закрытия обязательно "вспоминаем" его номер,
;номер у нас был сохранён в Handle.
int 21h ;Выполняем функцию.

mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset Vse_ok ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.

int 20h ;Выходим в DOS.

Error_file_metka: ;Вывод сообщения об ошибке.
mov ah,9 ;Загружаем в регистр ah число 9 (указываем функцию).
mov dx,offset Error_file ;Указываем, что за фразу мы будем выводить.
int 21h ;Выводим фразу.

int 20h ;Выходим в DOS.


File_name db '1.txt',0,'!$' ;Определяем переменную File_name (доступную побайтно),
;с именем файла. Путь к файлу не указан, это значит,
;что файл находится в текущем каталоге.
Handle dw 0 ;Определяем переменную Handle, которую используем для
;хранения номера файла. Первоначально она будет равна 0.

one db '1' ;Определяем переменную one, содержащую символ "1",
;которую мы будем приписывать в конец файла.

Vse_ok db 'Успешно!$' ;Определяем переменную Vse_ok, доступную побайтно, с фразой
;"Успешно!". В одинарных кавычках, после знака "!" ставим
;знак "$".

Error_file db 'Ошибка!$' ;Определяем переменную Vse_ok, доступную побайтно, с фразой
;"Ошибка!". В одинарных кавычках, после знака "!" ставим
;знак "$".


;Завершение программы.
CSEG ends
end begin


Обязательно посмотрите программу через отладчик.



Помните, пока для нас связка "HELP.EXE — текст программы в Far — отладчик" — неотъемлемая часть обучения. Иначе обучение сильно затянется!

В избранное