asm / Команды прерывания для студентов
.pdf11
.data |
|
|
|
handle |
dw |
0 |
;дескриптор файла |
filename |
db |
'my_file.txt',0 |
|
point_fname |
dd |
filename |
|
.stack256 |
|
|
|
.486 |
|
|
|
.code |
|
|
|
main: |
|
|
|
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
|
mov |
ds,ax |
|
;ax в ds |
;удаляем файл: |
|
|
|
mov |
ah,41h |
|
|
lds |
dx,point_fname |
;формируем указатель на имя файла |
|
xor |
cx,cx |
|
;атрибуты файла |
int |
21h |
|
|
;выход из программы |
|
|
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
|
int |
21h |
|
;вызов прерывания с номером 21h |
end main |
|
|
;конец программы с точкой входа main |
Функция 41h не позволяет удалять файлы с атрибутом «только для чтения». В этом случае необходимо изменить атрибуты удаляемого файла с помощью функции 43h.
7. Создание временного файла
Вход: АН = 5Ah; СХ = атрибуты файла; DS:DX – указатель на ASCIZ-строку с путем, заканчивающимся символом ‘\’ и 13 дополнительными нулевыми байтами, которые в результате вызова функции будут заполнены символами сгенерированного имени.
Выход: CF = 0 – АХ = дескриптор файла, открытого для чтения/записи в режиме совместимости; DS:DX – путь к файлу, дополненный сгенерированным именем временного файла; CF=1 – АХ = код ошибки: 3 – нет такого пути; 4 – нет свободного дескриптора файла; 5 – в доступе отказано; 50h – файл существует.
Врезультате вызова функции 5Ah создается файл с уникальным именем, который после своего закрытия должен быть явно удален создавшей его программой. Закрытие файла производится функцией 3Eh:
Вслучае задания имени, как в примере выше, файл будет создан в корневом каталоге текущего диска. Для того чтобы разместить файл в конкретном каталоге, необходимо указать полный путь к нему с завершающим символом '\’ и 13 нулевыми байтами на конце, например:
filename db 'e:\asm_on_a\',13 dup(0),0
Чтение, запись, позиционирование в файле
При работе с материалом данного раздела помните, что функции чтения и записи можно использовать не только с дескрипторами заранее открытых файлов, но и с дескрипторами стандартных устройств. Эти дескрипторы имеют постоянное значение и доступны в любое время функционирования системы: 0 – клавиатура; 1 и 2 – экран; 3 – последовательный порт СОМ1; 4 – параллельный порт LPT1.
1. Установка текущей файловой позиции
Чтение-запись в файле производятся с текущей файловой позиции, на которую указывает файловый указатель. Функция 42h MS DOS предоставляет гибкие возможности как для начального, так и для текущего позиционирования файлового указателя для последующей операции вводавывода.
Вход: АН = 42h; BX = дескриптор файла, полученный при его открытии; AL = начальное положение в файле, относительно которого производится операция чтения-записи (00h – смещение (беззнаковое значение в CX:DX) от начала файла; 01h – смещение (значение со знаком в CX:DX) от текущей позиции в файле; 02h – смещение (значение со знаком в СХ:DХ) от конца файла); CX:DX = смещение новой позиции в файле относительно начальной.
12
Выход: CF = 0 – DX:AX = значение новой позиции в байтах относительно начала файла; CF=1 – АХ = код ошибки: 1 – неверное значение в AL; 6 – недопустимый дескриптор файла.
Методы позиционирования, заданные величиной в AL, no-разному трактуют значение в паре регистров CX:DX. Метод al = 00 трактует значение в CX:DX как абсолютное. Два других метода (al=01 и al=02) трактуют содержимое СХ:DХ как значение со знаком. Необходимо быть внимательным при выполнении операции позиционирования для избежания последующих ошибок при операции чтения-записи. Так, значение в CX:DX, позиционирующее указатель, может указывать за пределы файла. При этом выделяются два случая:
–значение в CX:DX указывает на позицию перед началом файла – в этом случае последующая операция чтения-записи будет выполнена с ошибкой;
–значение в CX:DX указывает на позицию за концом файла – в этом случае последующая операция записи приведет к расширению файла в соответствии со значением в CX:DX,
2. Запись в файл или устройство
Запись в файл производится функцией 40h с текущей позиции файлового указателя.
Вход: АН = 40h; BX = дескриптор файла; СХ = количество байтов для записи; DS:DX – указатель на область, из которой записываются данные.
Выход: CF=0 – АХ = число действительно записанных байтов в файл или устройство; CF=1
– АХ = код ошибки: 5 – в доступе отказано; 6 – недопустимый дескриптор.
Если при вызове функции 40h регистр СХ равен нулю, то данные в файл не записываются и он усекается или расширяется до текущей позиции файлового указателя. Если СХ не равен нулю, то данные в файл записываются начиная с текущей позиции файлового указателя. Операция записи также продвигает файловый указатель на число действительно записанных байтов.
Положение файлового указателя можно изменять явно с помощью функции 42h.
;----------------------------------------------------------
;программа демонстрации вывода на экран строки функцией 40h. ;----------------------------------------------------------
masm |
|
|
|
|
model small |
|
|
|
|
.data |
|
|
|
|
string |
db |
'строка для вывода на экран функцией 40h' |
||
len_string=$-string |
|
|
||
point_fname |
dd |
string |
|
|
.stack |
256 |
|
|
|
.486 |
|
|
|
|
.code |
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
|
|
||||
|
mov |
ds,ax |
;ax в ds |
|
|
mov |
bx,1 |
;стандартный дескриптор - экран |
|
|
mov |
cx,len_string |
|
|
|
lds |
dx,point_fname |
;формируем указатель на строку string |
|
|
mov |
ah,40h |
;номер функции DOS |
|
|
int |
21h |
;выводим |
|
|
jc |
exit |
;переход в случае ошибки |
|
exit: |
nop |
;для тестирования |
||
|
|
|
|
|
;выход из программы |
|
|
||
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
|
|
int |
21h |
;вызов прерывания с номером 21h |
|
end |
main |
|
;конец программы с точкой входа main |
|
3. Чтение из файла или устройства
Чтение из файла в область памяти осуществляется функцией 3Fh.
Вход: АН = 3Fh; BX = дескриптор файла; СХ = количество байтов для чтения; DS:DX – указатель на область памяти, в которую помещаются прочитанные байты.
Выход: CF = 0 – АХ = число действительно прочитанных байтов из файла; CF = 1 – АХ = код ошибки: 5 – в доступе отказано; 6 – недопустимый дескриптор.
13
Чтение данных производится начиная с текущей позиции в файле, которая после успешного чтения смещается на значение, равное количеству прочитанных байтов. Если в качестве файла используется стандартная консоль (клавиатура), то чтение производится до первого символа CR (carriage return) с кодом 0dh, соответствующего нажатию клавиши Enter. Это, кстати, еще один способ ввода данных с клавиатуры в программу. Кроме символов введенной строки в ее конец помещаются символы 0dh и 0ah. Это необходимо учитывать при задании размера.
Не забывайте после определения размера файла возвращать файловый указатель в нужное место файла.
Получение и изменение атрибутов файла
MS DOS позволяет получить для анализа и при необходимости изменить имя файла, байт атрибутов файла, время и дату его последней модификации в элементе каталога, соответствующего этому файлу. Для этого предназначены функции 43h, 56h, 57h. Подфункция 00 функции 43h прерывания 21h предназначена для получения слова атрибутов файла.
1. Получить атрибуты файла
Вход: АХ=4300h; DS:DX – ASCIZ-строка с именем (путем) файла.
Выход: CF=0 – СХ = слово атрибутов файла; CF=1 – АХ = код ошибки: 1 – неверное значение в AL; 2 – файл не найден; 3 – несуществующий путь; 5 – доступ запрещен.
;----------------------------------------------------------
;программа демонстрации получения атрибутов файла.
;---------------------------------------------------------- |
|
|
|
|
masm |
|
|
|
|
model small |
|
|
|
|
.data |
|
|
|
|
fname |
db |
"maket.asm" |
|
|
point_fname |
dd |
fname |
|
|
.stack |
256 |
|
|
|
.486 |
|
|
|
|
.code |
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
|
|
||||
|
mov |
ds,ax |
;ax в ds |
|
;--------- |
получим атрибуты файла |
--------------------------------------------- |
||
|
lds |
dx,point_fname |
;формируем указатель на строку string |
|
|
mov |
ax,4300h |
;номер функции DOS |
|
|
int |
21h |
|
|
|
jc |
exit |
;переход в случае ошибки |
|
;в cx атрибуты (см. ниже) |
|
|||
exit: |
nop |
;для тестирования |
||
|
|
|
|
|
;выход из программы |
|
|
||
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
|
|
int |
21h |
;вызов прерывания с номером 21h |
|
end |
main |
|
;конец программы с точкой входа main |
|
|
Формат байта атрибутов: |
|||
Биты |
|
Описание |
|
|
7 |
Разделяемый в Novell NetWare |
|||
6 |
Не используется |
|
||
5 |
Архивный |
|
|
|
4 |
Каталог |
|
|
|
3 |
Метка тома (только исполнение Novell NetWare) , |
|||
2 |
Системный |
|
|
|
1 |
Скрытый |
|
|
|
0 |
Только чтение |
|
||
14
2. Установить атрибуты файла
Подфункция 01 функции 43h прерывания 21h предназначена для установления слова атрибутов файла.
Вход: АХ=4301h; СХ – новое слово атрибутов файла; DS:DX – ASCIZ-строка с именем (путем) файла.
Выход: CF=0 – АХ – не определен; CF=1 – АХ = код ошибки: 1 – неверное значение в AL; 2
– файл не найден; 3 – несуществующий путь; 5 – доступ запрещен.
3. Переименовать файл
Для переименования файла используется функция 56h.
Вход: АН = 56h; DS:DX – ASCIZ-имя существующего файла; ES:DI – ASCIZ-имя нового файла; CL = маска атрибутов.
Выход: CF=0 – при успешном переименовании; CF=1 – АХ = код ошибки: 2 – файл не найден; 3 – несуществующий путь; 5 – доступ запрещен; 11h – устройства для старого и нового файлов не совпадают. Функция 56h позволяет произвести перемещение между каталогами, не изменяя устройства.
;----------------------------------------------------------
;программа перемещения между каталогами, не изменяя устройства Функцией 56h.
;---------------------------------------------------------- |
|
|
|
|
masm |
|
|
|
|
model small |
|
|
|
|
.data |
|
|
|
|
fname_s |
db |
"maket.asm",0 |
||
point_fname_s |
dd |
fname_s |
|
|
fname_d |
db |
"e:\maket.asm",0 |
||
point_fname_d |
dd |
fname_d |
|
|
.stack |
256 |
|
|
|
.486 |
|
|
|
|
.code |
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных в регистр ax |
|
|
||||
|
mov |
ds,ax |
|
;ax в ds |
;-----переместим файл из текущего в корневой каталог------------------- |
||||
|
lds |
dx,point_fname_s |
;формируем указатель на строку fname_s (исх. файл) |
|
|
les |
di,point_fname_d |
;формируем указатель на строку fname_d (целевой файл) |
|
|
mov |
ah,56h |
|
;номер функции DOS |
|
int |
21h |
|
|
|
jc |
exit |
|
;переход в случае ошибки |
;в cx атрибуты (см. ниже) |
|
|||
|
nop |
;для тестирования |
||
exit: |
;выход из программы |
|
||
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
|
|
int |
21h |
;вызов прерывания с номером 21h |
|
end |
main |
|
;конец программы с точкой входа main |
|
|
4. Получить дату и время создания или последней модификации файла |
|||
|
Получить/изменить дату и время создания или модификации файла можно с помощью |
|||
подфункций функции 57h. |
|
|||
Вход: АХ=5700h; BX=дескриптор файла.
Выход: если CF = 0: СХ = время, DX = дата. Если CF = 1: АХ – код ошибки (CF=1): 1 – недопустимый номер подфункции в Аl; 6 – недопустимый дескриптор. Время и дата файла получа-
ются в следующих форматах. |
|
|
|
Время |
|
Дата |
|
Биты |
Описание |
Биты |
Описание |
15-11 |
Часы (0-23) |
15-9 |
Год |
10-5 |
Минуты |
8-5 |
Месяц |
4-0 |
Секунды |
4-0 |
День |
5. Установить дату и время создания или последней модификации файла
Вход: АХ = 5701h; BX = дескриптор файла; СХ = новое время, DX = новая дата.
Выход: если CF = 0: СХ - время, DX = дата. Если CF = 1 – АХ – код ошибки: 1 – недопустимый номер подфункции в А1; 6 — недопустимый дескриптор.
15
Работа с дисками, каталогами и организация поиска файлов
Рассмотрим номенклатуру средств, предлагаемых MS DOS для поиска файла и определения его местоположения в древовидной структуре каталогов текущего диска.
Во время работы с предыдущими программами при задании имен файлов мы практически не указывали имен дисководов и путей к этим файлам. MS DOS имеет средства для установки текущего диска и каталога, в котором выполняются все текущие операции с файлами. При необходимости можно изменить текущий диск и каталог.
Получить номер заданного по умолчанию дисковода
Вход: АН =19h.
Выход: AL = номер дисковода (00h=A:, 0lh=В: и т. д.).
;программа получения номера текущего (по умолчанию) ;дисковода функцией 19h.
.code
…
mov ah, l9h ;номер функции DOS int21h
jc exit ;переход в случае ошибки ;в al номер текущего диска
Выбрать заданный по умолчанию диск
Вход:
АН = 0Eh;
DL = номер нового диска по умолчанию (00h=A:, 0lh=В: и т. д.).
Выход: AL = максимально возможный в данной системе номер дисковода (00h=A:, 0lh = В: и т. д.) определяется на основе параметра LASTDRIVE в файле CONFIG.SYS.
Получить информацию о свободном дисковом пространстве
Вход: АН = 36h; DL = номер диска (00h = текущий, 0lh = А: и т. д.). Выход: АХ = FFFFh — неправильный номер устройства в DL,
иначе: АХ = число секторов в одном кластере; ВХ = число свободных кластеров; СХ = размер сектора (в байтах); DX = общее число кластеров на диске.
Используя информацию, возвращаемую функцией 36h, можно подсчитать как свободное пространство на диске – произведение АХ*ВХ*СХ, так и полный объем диска — произведение
AX*CX*DX.
MS DOS предоставляет следующие возможности для манипулирования каталогами: создание и удаление каталога, получение информации о текущем каталоге и его смена.
Создание каталога
Вход: АН = 39h; DS:DX – ASCIZ-строка пути к создаваемому каталогу. Выход: АХ = не определен (CF = 0);
АХ = код ошибки (CF = 1): 3 – несуществующий путь; 5 — доступ запрещен.
Путь к каталогу должен содержать перечисление всех каталогов начиная от корневого на пути к создаваемому каталогу, при этом они, естественно, должны существовать. Последнее имя каталога — имя создаваемого каталога.
;----------------------------------------------------------
;программа демонстрации создания каталога функцией 39h.
;---------------------------------------------------------- |
|
|
masm |
|
|
model small |
|
|
.data |
|
|
dname db |
"c:\windows\my_dir",0 |
|
point_dname |
dd |
dname |
16
.stack |
256 |
|
|
|
|
.486 |
|
|
|
|
|
.code |
|
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных - в регистр AX |
||
|
|||||
|
mov |
ds,ax |
;AX в DS |
|
|
;-----создадим каталог в каталоге c:\windows---------------- |
|||||
|
lds |
dx,point_dname |
;формируем указатель на строку с именем нового каталога |
||
|
mov |
ah,39h ;номер функции DOS |
|||
|
int |
21h |
|
|
|
|
jc |
exit |
;переход в случае ошибки |
||
exit: |
nop |
;для тестирования |
|
||
|
|
|
|
|
|
;выход из программы |
|
|
|||
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
||
|
int |
21h ;вызов прерывания с номером 21h |
|||
end |
main |
|
;конец программы с точкой входа main |
||
|
|
|
|
||
|
Удаление каталога |
|
|
||
|
Вход: АН = 3Ah; DS:DX – ASCIZ-строка пути к удаляемому каталогу. |
||||
|
Выход: CF = 0 — АХ = не определен; АХ = код ошибки (CF = 1): 3 — несуществующий! |
||||
путь; 5 — доступ запрещен; 10h — попытка удаления текущего каталога. Удаляемый каталог должен быть пустым. ;----------------------------------------------------------
;программа демонстрации удаления каталога функцией 3Ah. ;----------------------------------------------------------
masm |
|
|
|
|
|
|
model small |
|
|
|
|
||
.data |
|
|
|
|
|
|
dname db |
"c:\windows\my_dir",0 |
|||||
point_dname |
dd |
dname |
|
|
||
.stack |
256 |
|
|
|
|
|
.486 |
|
|
|
|
|
|
.code |
|
|
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
|||
|
|
|||||
|
|
mov |
ds,ax |
;ax в ds |
|
|
;----- |
удалим каталог my_dir в каталоге c:\windows---------------- |
|||||
|
|
lds |
dx,point_dname |
;формируем указатель на строку с именем нового каталога |
||
|
|
mov |
ah,3ah ;номер функции DOS |
|||
|
|
int |
21h |
|
|
|
|
|
jc |
exit |
;переход в случае ошибки |
||
exit: |
|
nop |
;для тестирования |
|
||
|
|
|
|
|
|
|
;выход из программы |
|
|
||||
|
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
||
|
|
int |
21h ;вызов прерывания с номером 21h |
|||
end |
|
main |
|
;конец программы с точкой входа main |
||
Изменить текущий каталог
MS DOS позволяет установить текущий каталог для того, чтобы не указывать полный путь для последующих операций с файлами. При необходимости можно получить полный путь к текущему каталогу в виде ASCIZ-строки.
Вход: АН = 3Bh; DS:DX — указатель на буфер, содержащий полный путь от корневого ка-
17
талога в виде ASCIZ-строки (до 64 байт).
Выход: CF = 0 — АХ = не определен; CF = 1 — АХ = код ошибки: 03h — путь не найден! ;----------------------------------------------------------
; программа демонстрации изменения текущего каталога функцией 3Bh.
;---------------------------------------------------------- |
|
|
|
|
|
|
masm |
|
|
|
|
|
|
model small |
|
|
|
|
||
.data |
|
|
|
|
|
|
dname db |
"c:\windows",0 |
|
||||
point_dname |
dd |
dname |
|
|
||
.stack |
256 |
|
|
|
|
|
.486 |
|
|
|
|
|
|
.code |
|
|
|
|
|
|
main: |
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
|||
|
|
|||||
|
|
mov |
ds,ax |
;ax в ds |
|
|
;----- |
изменим текущий каталог на каталог c:\windows---------------- |
|||||
|
|
lds |
dx,point_dname |
;формируем указатель на строку с именем нового каталога |
||
|
|
mov |
ah,3bh ;номер функции DOS |
|||
|
|
int |
21h |
|
|
|
|
|
jc |
exit |
;переход в случае ошибки |
||
exit: |
|
nop |
;для тестирования |
|
||
|
|
|
|
|
|
|
;выход из программы |
|
|
||||
|
|
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
||
|
|
int |
21h ;вызов прерывания с номером 21h |
|||
end |
|
main |
|
;конец программы с точкой входа main |
||
Получение текущего каталога
Вход: АН = 47h;
DL = номер устройства (00h = текущее (по умолчанию), 0lh = А: и т. д.) DS:SI — указатель на 64-байтный буфер для записи полного пути от корневого каталога (ASCIZ-строка).
Выход: АХ = не определен или 0100h (CF=0);
АХ = код ошибки (CF=1): 0Fh — недопустимый дисковод. ;----------------------------------------------------------
;программа демонстрации получения текущего каталога функцией 47h.
;---------------------------------------------------------- |
|
|
|
|
|
masm |
|
|
|
|
|
model small |
|
|
|
|
|
.data |
|
|
|
|
|
dname db |
"e:\tools",0 |
|
|
||
point_dname |
dd |
dname |
|
|
|
d_cur_name |
db |
64 dup (20h),0 |
|
||
point_d_cur_name |
dd |
d_cur_name |
|||
.stack 256 |
|
|
|
|
|
.486 |
|
|
|
|
|
.code |
|
|
|
|
|
main: |
|
|
|
|
|
|
mov |
ax,@data |
;адрес сегмента данных - в регистр ax |
||
|
mov |
ds,ax |
;ax в ds |
|
|
;----- |
изменим текущий каталог на каталог \tools ---------------- |
||||
|
lds |
dx,point_dname |
;формируем указатель на строку с именем нового каталога |
||
|
mov |
ah,3bh ;номер функции DOS |
|||
|
int |
21h |
|
|
|
18
jc |
exit |
;переход в случае ошибки |
|
;-----получим текущий каталог---------------- |
|||
lds |
si,point_d_cur_name ;формируем указатель на строку с именем нового каталога |
||
mov |
ah,47h ;номер функции DOS |
||
int |
21h |
|
|
jc |
exit |
;переход в случае ошибки |
|
nop |
;для тестирования |
||
exit: |
|
|
|
;выход из программы |
|
||
mov |
ax,4c00h |
;пересылка 4c00h в регистр ax |
|
int |
21h |
;вызов прерывания с номером 21h |
|
end main |
|
;конец программы с точкой входа main |
|
Возвращаемый путь не содержит имени диска и первого символа \.
