Информация


Programm.ws - это сайт, на котором вы можете почитать литературу по языкам программирования, а так-же посмотреть примеры работающих программ на С++, ассемблере, паскале и много другого..

Программирование — в обычном понимании, это процесс создания компьютерных программ.
В узком смысле (так называемое кодирование) под программированием понимается написание инструкций — программ — на конкретном языке программирования (часто по уже имеющемуся алгоритму — плану, методу решения поставленной задачи). Соответственно, люди, которые этим занимаются, называются программистами (на профессиональном жаргоне — кодерами), а те, кто разрабатывает алгоритмы — алгоритмистами, специалистами предметной области, математиками.
В более широком смысле под программированием понимают весь спектр деятельности, связанный с созданием и поддержанием в рабочем состоянии программ — программного обеспечения ЭВМ. Более точен современный термин — «программная инженерия» (также иначе «инженерия ПО»). Сюда входят анализ и постановка задачи, проектирование программы, построение алгоритмов, разработка структур данных, написание текстов программ, отладка и тестирование программы (испытания программы), документирование, настройка (конфигурирование), доработка и сопровождение.

Глава 7. Работа с файлами в программах на ассемблере

Работа с файлами в MS DOS (длинные имена)

Перечисленные выше функции работают в различных версиях «чистой» системы MS DOS, вплоть до версии 6.22 включительно. Операционные системы Windows 95/98/Mil также поддерживают свою версию MS DOS, которая имеет номер 7.0. Операционная система Windows 95/98/Mil организует для программ MS DOS специальную среду для работы, называемую сеансом DOS. Система MS DOS 7.0, будучи созданной для работы в среде Windows 95/98/Mil, имеет в своем составе средства для работы с файловой системой Windows. Эта файловая система, как известно, отличается тем, что полное имя файла может достигать длины 255 символов. MS DOS 7.0 также умеет работать с длинными именами файлов. В данном разделе мы рассмотрим предназначенные для работы с файловой системой Windows средства среды MS DOS, работающей под управлением
Windows.
Определить факт того, в какой системе работает программа, можно по результатам работы функций 30h — получить версию DOS (прерывания 21п) и 4аЗЗп (прерывания 2fh).
Вход: АН = 30h; AL = определяет значение, возвращаемое в ВН: 00h— OEM-номер (как для DOS 2.0-4.0x);01h — номер версии.
Выход: AL = главный номер версии; АН - младший номер версии; BL:CX = 24-битный серийный номер пользователя (необязательно).


:prg07_19.a$m - программа демонстрации определения факта того. ;в какой системе работает программа.
.code
;.....определим номер версии ОС MS DOS
mov al .00
movah.30h ;номер функции DOS
int21h ;А1-главный номер версии. АН-младший номер версии
]с exit ;переход в случае ошибки

В регистрах AL и АН возвращаются главный и младший номера версии MS DOS. При функционировании под Windows эти номера равны 07h и Oah соответственно. Задание значения AL = 01 дает такой же эффект.

:prg07_20.asm - программа демонстрации определения факта работы в среде MS DOS 7.0.
.code
:-----определить факт работы в среде MS DOS 7.0
movax.4a33h ;номер функции DOS int 2fh
cmp ax, 0
jneexit ;переход, если работа не в среде MS DOS 7.0

Последняя функция возвращает 0 для MS DOS версии 7.0 и выше. Установить факт того, что система поддерживает длинные имена файлов, можно вызовом функции 71a0h прерывания 21п — получить информацию о томе. Если она возвращает ошибку (CF = 1), то текущая файловая система не поддерживает длинных имен файлов. Для вызова этой функции необходимо указать корневой каталог тома, о котором необходимо получить информацию. Вход: АХ = 71A0h; DS:SI — ASCIZ-имя корневого каталога тома, о котором необходимо получить информацию (например, "С:\"); ES:DI — буфер для имени файловой системы; СХ ¦= размер буфера, адрес которого задан в ES: DI (32 байта).
Выход: CF = 0 в случае успеха, следующие регистры установлены: ВХ = флаги файловой системы: 0 — при поиске учитывать регистр букв в именах файлов; 1 — сохранять регистр букв в элементах каталога; 2 — использование символов Unicode в именах каталогов и файлов; 3-13 — резерв (0); 14 — поддержка DOS-функций для длинных имен файлов; 15 — сжатый том; СХ = максимальная длина файловых имен (обычно 255); DX = максимальная длина пути (обычно 260); ES: DI — в буфере по этому адресу ASCIZ-имя файловой системы, например "FAT", "FAT32", "NTFS", "CDFS"; CF = 1 в случае неудачи, при этом АХ = код ошибки или AX=7100h, если функция не поддерживается.
В Windows 95/98 появились дополнительные возможности как самой файловой системы, так и средств по ее управлению. Основное нововведение — поддержка длинных имен файлов. Основа файловой системы та же — таблица разрешения файлов FAT, но любой файл в этой системе имеет два имени — длинное имя и его псевдоним, который соответствует формату 8.3. Данный псевдоним создается системой Windows 95/98 автоматически.
Нужно правильно понимать различие в способах использования длинных имен файлов в приложениях MS DOS и Win32. Приложения MS DOS получают до-ступ к длинным именам файлов с помощью дополнительных функций прерывания 21h. Приложения Windows используют для этого соответствующие функции API.
Длинное имя файла представляет собой ASCIIZ-строку длиной до 255 символов. Система формирует псевдоним для этого имени форматом 8.3 в соответствии со следующим правилом: берутся первые 6 символов длинного имени, после них добавляется символ тильда (-), за тильдой ставится некий порядковый номер. Для первого имени формата 8.3 это 1. Если такой псевдоним уже существует, то порядковый номер очередного псевдонима будет на 1 больше. Расширение псевдонима формируется из первых трех символов расширения длинного имени (если оно существует). Если похожих имен много, то номер в псевдониме может быть двузначным, при этом первая (символьная) часть псевдонима сокращается
до 5 символов, и т. д.
Рассмотренные выше функции MS DOS для работы с файлами и каталогами не поддерживают длинных имен. Для этого система Windows 95/98 предоставляет приложениям MS DOS аналогичные функции, но имеющие другие номера. Впрочем, при внимательном рассмотрении большинства из этих номеров, видно, какой из старых функций они соответствуют. Новые номера состоят из четырех цифр: первые две — 071h, последние две — номер старой функции. Для некоторых функций существуют особенности в их работе. Так, для поиска файлов по-прежнему используются две функции (по новой нумерации — 714eh и 714fh) прерывания 21h. Новые функции теперь возвращают информацию о файлах через специальную структуру WI N32_F INDDATA, адрес которой возвращается в качестве
результата их работы.
При работе с функциями, поддерживающими длинные имена файлов, используются еще две структуры: by handle_f 11 e_information и filetime. Назначение структуры by_hand1e_file_iinformation и работу с ней мы рассмотрим при обсуждении функции MS DOS 71a6h. Структура filetime содержит 64-разрядное значение, которое определяет число 100-наносекундных интервалов, прошедших с 12:00 утра 1 января 1901 года.

FILETIME Struc
DwLowDateTime dd ? :младшие 32 бита значения времени DwHighDateTime dd ? хтаршие 32 бита значения времени FILETIME ends

Теперь приведем перечень функций прерывания 21h, работающих с файлами, которые имеют длинные имена. Для удобства дальнейшего рассмотрения в следующей таблице приведены соответствующие функции API WIN32 и «старые» функции прерывания 21h.

Новая
функция int 21h
Старая функция int 21h
Назначение
 
Функция API Win32
 
5704h
 

Получить дату и время последнего доступа
GetFileTime
5705h
 

Установить дату и время
SetFileTime
 

 

последнего доступа
 

5706h
 

Получить дату и время создания
GetFileTime
5707h
 

Установить дату и время создания
SetFileTime
7139h
39h
Создать каталог
CreateDirectory
713Ah
3ah
Удалить каталог
RemoveDirectory
713Bh
3bh
Изменить текущий каталог
SetCurrentDi rectory
7141h
41h
Удалить файл
DeleteFile
7143h
43h
Получить или установить
GetFileAttributes,
 

 

атрибуты файла
SetFileAttributes
7147h
47h
Получить текущий каталог
GetCurrentDirectory
714Eh
4Eh
Найти первый файл
FindFirstFile
714Fh
4Fh
Найти следующий файл
FindNextFile
7156h
56h
Переименовать файл
MoveFile
7160h
 

Получить полный путь
GetFullPathName
7160h
 

Получить полный путь
GetShortPathName
 

 

с-краткими именами
 

7160h
 

Получить полный путь
Отсутствует
 

 

с длинными именами
 

716Ch
3ch, 3dh, 5bh
Создать или открыть файл
CreateFile, OpenFile
71A0h
 

Получить информацию о томе
GetVolumelnfonnati on
71Alh
 

Завершить поиск
FindClose
71A6h
 

Получить информацию о файле
GetFi1 elnformationByHandle
 

 

по описателю
 

71A7h
 

Преобразовать время файла
Fi1eTi meToDOSDateTime
 

 

в DOS-время
 

71A7h
 

Преобразовать DOS-время во время файла
00SDateTi meToFi1eTi me
71A8h
 

Создать псевдоним
Отсутствует
71A9h
 

Создать или открыть файл
Отсутствует
 

 

на сервере
 

71AAh
 

Провести подмену
Отсутствует
71AAh
 

Отменить подмену
Отсутствует
71AAh
 

Получить информацию
Отсутствует
 

 

о подмене
 

Рассмотрим наиболее интересные в контексте нашего изложения функции этой таблицы. Информацию по остальным функциям можно получить, в частности, из MSDN. Порядок рассмотрения будет от простых функций к сложным, так как это было в предыдущем разделе, посвященном функциям работы с файлами ДО DOS, имеющими короткие имена.

Создание, открытие, закрытие и удаление файла

функции MS DOS, поддерживающие длинные имена файлов, имеют номера из четырех цифр — первые две равны 71h, последние две соответствуют номеру аналогичной старой функции MS DOS. В программах старые и новые функции применяются вместе по принципу: там, где функция должна работать непосредственно с длинными именами файлов и каталогов, применяются новые функции; там, где функция работает с дескриптором файла, используются старые функции. Новые функции также используются для реализации новых возможностей по работе с файловой системой.

Открытие или создание файла

Для создания или открытия файла с длинным именем используется функция 716Ch (создать или открыть файл). Эта функция аналогична функции 6ch, которая появилась в последних версиях MS DOS (DOS 4.0+). Мы уже обсуждали ее в разделе, посвященном функциям работы с файлами с короткими именами.
Вход: АХ = 716Ch; BX = режимы доступа и флаги:
режим доступа: 0000h — файл только для чтения; 0001h — файл только для записи; 0002h — файл для чтения и записи; 0003h — резерв; 0004п — открыть файл для чтения без изменения даты последнего доступа к файлу; режим разделения: 0000h — режим эмуляции — файл можно открывать любой программе любое количество раз; 00Wh — файл открыт в монопольном режиме доступа; 0020h — файл открыт в монопольном режиме доступа по записи; 0030h — файл открыт в монопольном режиме доступа по чтению; 0040И — открыть файл, разрешая другим процессам доступ по чтению-записи, но с запретом режима эмуляции; флаги: 0080h — дочерний процесс не наследует дескриптор файла, его при необходимости нужно передавать явно; Ol00h — не использовать буферизацию или кэширование средствами ОС, операции чтения-записи выполняются напрямую с диском в соответствии с текущим положением файлового указателя; 0200h — файл нельзя сжимать; 0400h — содержимое регистра 01 следует использовать как порядковый номер в псевдониме файла; 2000h — не вызвать обработчик критической ошибки (int 24h), MS DOS вернет программе код ошибки; 4000h — после каждой операции записи MS DOS будет отправлять данные на диск без их кэширования; СХ - атрибуты создаваемого (и только) файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004п — системный файл; 0008h — метка тома; 0020h — архивный
файл;
DX ~ действия, если файл существует или не существует, значения битов: 00lOh — вернуть ошибку, если файл существует, иначе создать файл; 0001h — открыть файл, если он существует, иначе вернуть ошибку;

0002h — открыть файл без сохранения существующего, иначе вернуть ошибку (если файл не существует); DS:SI — ASCIZ-имя файла;
DI — порядковый номер, который добавляется к концу имени в псевдониме файла (для этого должен быть задан флаг 0400h в регистре ВХ) Номер будет десятичным письмом, то есть если DI=0010h, то конец псевдонима -----16.
Выход: CF=0 — успешное выполнение функции: АХ = дескриптор файла, СХ = состояние: 1 — файл открыт; 2 — файл создан и открыт; 2 — файл открыт без сохранения содержимого существующего файла; CF=1: AX = код ошибки.
После того как файл открыт или создан функцией 716ch, с ним можно работать, используя старые функции чтения-записи и позиционирования. Следующий фрагмент программы показывает вариант применения функции 716Ch.
Закрытие файла производится функцией 3Eh, которая использовалась для файловых функций MS DOS с короткими именами.

Удаление файла

Удаление файлов, имеющих длинные имена, производится функцией 7141h прерывания 21п. Имя файла может быть задано с использованием символов шаблона * и ?, при этом в результате работы функции будут удалены все файлы, чье имя удовлетворяет заданному шаблону.

Получить дату и время создания файла

Вход: АХ = 5706h; ВХ - дескриптор файла. ; . М
Выход: CF = 0 — успешное выполнение функции: СХ = биты установлены следующим образом: 0..4 - секунды, деленные на 2; 5..10 = минуты 0..59; 11..15 -часы; DX - биты установлены следующим образом: 0..4 = день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15 = число лет начиная с 1980 года; SI - двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199; CF = 1: АХ = код ошибки.
Данная функция реализована в полном объеме.

Установить дату последней модификации файла

Вход: АХ = 5705И; ВХ = дескриптор файла; СХ = 0000h; DX - биты установлены следующим образом: 0..4 - день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15- число лет, начиная с 1980 года.
Выход: CF = 0 — успешное выполнение функции; CF = 1: АХ код ошибки.

Аналогично функции 5704h данная функция позволяет установить только дату создания файла.

Установить дату и время создания или последней модификации файла

Вход: АХ = 5707h; ВХ = дескриптор файла; СХ - биты установлены следующим образом: 0..4 - секунды, деленные на 2; 5..10 = минуты 0..59; 11..15 - часы; DX " биты установлены следующим образом: 0..4 = день месяца в диапазоне 1..31; 5..8 = месяц в диапазоне 1..12; 9..15 = число лет начиная с
1980 года;
SI - двоичное значение количества 10-миллисекундных интервалов, добавляемых к времени MS DOS в диапазоне 0..199.
Выход: CF = 0 — успешное выполнение функции; CF = 1: АХ - код ошибки.

Данная функция реализована в полном объеме.
Кроме дополнительных функций для работы с различными временными характеристиками файла Windows-версия MS DOS содержит две функции для преобразования форматов времени. Дело в том, что Windows работает со временем в 64 разрядном формате. При этом точкой отсчета является 00 часов 00 минут 1 января 1601 года. Значение времени содержит число 100-наносекундных интервалов, прошедших с этой даты. По расчетам разработчиков этого значения должно хватить на 400 лет. Для того чтобы манипулировать этим 64-разрядным «средневековьем» с целью представления его в виде, воспринимаемом человеком (DOS-время), введена функция 71a7h.
Вход: АХ = 71a7h; BL = 0 — преобразовать 64-разрядное время в DOS-время; DS:SI = указатель на экземпляр структуры FILETIME, содержащей 64-битное значение времени.
Выход: CF = 0 — успешное выполнение функции, при этом регистры устанавливаются следующим образом: ВН = число 10-миллисекундных интервалов, добавляемых к времени MS DOS (значение в диапазоне 0..199); СХ - время в упакованном формате со значением бит: 0..4 — секунды, деленные на 2; 5..10 — минуты в диапазоне 0..59; 0..4 — часы в диапазоне 0..23; DX = дата в упакованном формате со значением бит: 0..4 — день месяца в диапазоне 1.31; 5..8 — месяц в диапазоне 1..12; 9..15 — число лет начиная с 1980 года (для получения истинного значения прибавьте 1980); CF = 1: АХ - код ошибки. (Структура filetime описывается в программе следующим образом:

FILETIME struc
DwLowOateTime dd ? :младшие 32 бита значения времени
DwHighDateTime dd ? :старшие 32 бита значения времени
FILETIME ends

Вход: АХ = 71a7h; BL - 1 — преобразовать DOS-время в 64-разрядное время; ВН = число 10-миллисекундных интервалов, добавляемых ко времени MS DOS (значение в диапазоне 0..199); СХ = время в упакованном формате со значением бит: 0..4 — секунды, деленные на 2; 5..10 — минуты в диапазоне 0..59; 0..4 — часы в диапазоне 0..23; DX - дата в упакованном формате со значением бит: 0..4 — день месяца в диапазоне 1..31; 5..8 — месяц в диа пазоне 1..12; 9..15 — число лет начиная с 1980 года (для получения истинного значения прибавьте 1980) DS:SI = указатель на экземпляр структуры FILETIME, в которой вернется 64-битное значение времени.
Выход: CF=O — успешное выполнение функции, при этом в области памяти, адресуемой DS:SI, возвращается 64-битное значение времени; CF=1: AX - код ошибки.

Получить атрибуты файла

Вход: АХ ¦ 7143h; BX = действие:
0 -- получить атрибуты, на выходе СХ = атрибуты файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004И — системный файл; 0008h — метка тома; 00lOh — каталог; 0020h — архивный файл;
2 — получить размер сжатого файла — на выходе DX:AX = размер сжатого файла в байтах на диске;
4 — получить дату и время последней записи — на выходе; СХ = время в формате: 0..4 = секунды, деленные на 2; 5.. 10 = минуты (0..59); 11..15 = часы(0..23);
DI дата в формате: 0..4 = день месяца (1..31); 5..8 = месяц (1..12); 9..15 = число лет с 1980 года;
6 — получить дату последнего доступа — на выходе: DI = дата в формате (см. ВХ = 4);
8 — получить дату и время создания — на выходе СХ - время в формате, DI - дата в формате (см. ВХ « 4), SI = двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199;
DS:DX — ASCIZ-строка с именем (путем) файла.
Выход: CF = 0 в случае успеха, информация в регистрах определяется значением ВХ на входе (см. выше):
АХ = код ошибки (CF = 1): 1 — неверное значение в AL; 2 — файл не найден; 3 — несуществующий путь; 5 — доступ запрещен.

Установить атрибуты файла

Вход: АХ = 7143h; ВХ = действие:
1 — установить атрибуты на входе СХ = атрибуты файла: 0000h — файл доступен по записи и чтению; 0001h — файл доступен по чтению; 0002h — скрытый файл; 0004h — системный файл; 0020h — архивный файл; 3 — установить дату и время последней записи: СХ = время в формате: 0..4 " секунды, деленные на 2; 5..10 = минуты (0..59); П..15 - часы (0..23); 01 = дата в формате: 0..4 = день месяца (1..31); 5..8 = месяц (Т.. 12); 9..15 =" число лет с 1980 года;
5 — установить дату последнего доступа (см. ВХ = 3); 7 — установить дату и время создания: СХ = время в формате (см. ВХ - 3), DI = дата в формате (см. ВХ = 3), SI = двоичное значение количества 10-миллисекундных интервалов, добавляемых ко времени MS DOS в диапазоне 0..199; DS:DX — ASCIZ-строка с именем (путем) файла.
Выход: CF = о — СХ = слово атрибутов файла; CF=1 — АХ=код ошибки: 1 — неверное значение в AL; 2 — файл не найден; 3 — несуществующий путь; 5 — до-ступ запрещен.

Переименовать файл

Вход: АН = 7156h; DS:DX — ASCIZ-имя существующего файла; ES:O1
имя нового файла; CL - маска атрибутов. Выход: CF = 0 — при успешном переименовании; CF = 1 — АХ = код ошибки: 2 —
файл не найден; 3 — несуществующий путь; 5 — доступ запрещен;
устройства для старого и нового файлов не совпадают.