Dos fn 10h закрыть файл через fcb


Электронная библиотека

Для выполнения операции ввода и вывода файлов в базовый DOS необходимо в сегменте данных определить блок управления файлов (FCB). Блок FCB содержит описание файла и его записей в следующем ниже формате. Программист должен инициализировать байты 0-15 и 32-36. Остальные байты установит DOS.

Дисковод, 01 для A, 02 для B и т.д., 0-текущий дисковод

Имя файла, дополненное справа пробелами

Номер текущего блока. Блок содержит 128 записей. Номер текущей записи находится в байте 32. Первый блок имеет номер 0. После открытия файла равен 0

Логический размер записи. При открытии файла устанавливается в 0. Можно установить любое другое число

Размер файла. Это поле изменить нельзя

Дата создания или изменения

Текущий номер записи в текущем блоке (см. байты 12-13)

Относительный номер записи

Для создания нового файла на диске используются следующие функции прерывания 21h:

16h — создание файла

1Ah — установка адреса области передачи данных DTA

15h — запись из области DTA в файл

10h — закрытие файла

В сегменте данных надо определить блок FCB и буфер DTA для данных, которые будут записываться на диск:

fcb db 1 ;дисковод A

blkptr dw 0 ;номер текущего блока

recsize dw ? ;размер записи

dw 8 dup(?) ;байты 16-31

recptr db 0 ;номер текущей записи

dw 2 dup(?) ;байты 33-36

buffer db 512 dup(?)

Для создания файла filename.ext выполнить команды

Размер записи устанавливается при открытии по умолчанию 128 байт.

Буфер, из которого будут записываться данные на диск, устанавливается командами

С помощью функции 15h осуществляется запись содержимого буфера DTA на диск:

Размер файла в блоке FCB и текущие номера записи и блока изменяет DOS. В конце работы следует закрыть файл:

Рассмотрим теперь операцию чтения файла по FCB. Для чтения файла необходимо вызвать следующие функции прерывания 21h:

0Fh — открытие файла

1Ah — формирование адреса буфера

14h — чтение данных из файла в буфер

Открытие файла осуществляется командами

Установка буфера DTA рассматривалась выше. После установки буфера DTA осуществляется чтение:

Так как при чтении файла записи в каталоге не изменяются, то нет необходимости закрывать файл после завершения чтения.

Напишем программу, читающую собственный текст и выводящую его на экран:

Dos fn 10h: закрыть файл через fcb

Assembler для начинающих

Прежде, чем перейти к упомянутому примеру, необходимо рассмотреть
формируемую DOS структуру данных — блок управления файлом FCB (File
Control Block), который является существенным элементом файловой
системы и участвует во всех файловых операциях.

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

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

Использование FCB при работе с файлами

21.01.2020, 06:36

Что такое FCB?
Что такое FCB? А то читаю: int 21-23 — Размер файла (FCB).

Многопоточность при работе с файлами
Доброй ночи! Написал код для сравнения двух файлов: string text, text2; .

Ошибка при работе с файлами
Sub â_ïðîåêòèðîâàíèå() If Dir(ActiveWorkbook.Path & «\Google Äèñê\Projects\» &.

Ошибка при работе с файлами
Вечер добрый! Есть код: string test; StreamReader rr =.

Ошибка при работе с файлами
Дан код. Необходимо при работе с фалом вывести на экран тех, кто достиг пенсионного возраста. При.

21.01.2020, 17:53 2

Решение

HYDRA8, вам обязательно выполнить работу с файлами, применяя именно FCB?
Существует ведь другой способ — через описатели (когда блоки FCB создаются и хранятся в недрах ОС, а программе пользователя возвращается порядковый номер этого блока — описатель).

По умолчанию FCB находится в области PSP по смещению 5Ch. Если вы используете тип файла exe, то область PSP вам так легко не доступна.
Ну и заполнять нужно этот FCB до вызова на открытие.

Вот пример набросал по чтению и выводу на экран текстового файла:

Как понимаю, если размер файла не кратен 80h — размеру записи, то нужно самостоятельно обрабатывать поле fFileSize на предмет кратности размеру записи и выводить только остаток. В моём примере этого нет и согласно функции 1Ah прерывания 21h в последней считанной записи все избыточные байты заполняются 0.

Можно слегка доработать ситуацию 3 при чтении — размер реально считанной записи равен fFileSize and 7Fh и именно столько символов и нужно выводить.

21.01.2020, 17:53

Ошибка при работе с файлами
Столкнулся с такой проблемой, что если выбран FileMode.OpenOrCreate, то значения в массив выводятся.

ArgumentException при работе с файлами
Почему так выходит?Как связать программу с файлом?

Алгоритм при работе с файлами
Возникла проблема в программе: 1. На входе имеем дирректорию, нам нужно обойти в ней все.

Whatis.Ru

Информация о компьютерах доступным языком
Назад на сайт

Страниц: 1 2

#26 18-01-2011 19:35:39

Re: . Введение в Ассемблер

Программа DEBUG

Программируем под DOS на ассемблере, используя виндовый DEBUG.

Программа DEBUG — мощный отладчик, входящий в состав Windows. Для запуска — жмём [Win+R] и вводим DEBUG. Перед нами мигающий курсор. Введём знак вопроса ? и получим список команд:

— A (assemble) — Создание двоичного кода процессоров 8086 непосредственно в памяти.
— С (compare) — Сравнение двух блоков памяти.
— D (dump) — Просмотр содержимого заданного диапазона адресов памяти.
— E (enter) — Ввод данных в память по заданному адресу.
— F (fill) — Заполнение адресов в области памяти заданными значениями.
— G (go) — Выполнение загруженной программы.
— H (hexadecimal) — Выполнение шестнадцатеричных арифметических операций.
— I (input) — Считывание и вывод на экран одного байта из указанного порта ввода.
— L (load) — Загрузка файла или содержимого сектора диска в память.
— M (move) — Копирование содержимого одного блока памяти в другой.
— N (name) — Задание имени исполняемого файла, L (load) или W (write).
— O (output) — Вывод байта в порт вывода.
— P (proceed) — Выполнение цикла, инструкции, прерывания или процедур.
— Q (quit) — Выход из Debug, без сохранения тестируемого файла.
— R (register) — Редактирование содержимого регистров ЦПУ.
— S (search) — Поиск в области памяти по шаблону.
— T (trace) — Выполнение одной инструкции с выводом содержимого регистров.
— U (unassemble) — Дезассемблирование и просмотр исходного кода программы.
— W (write) — Запись файла на диск.

Подробное описание команд с примерами можно найти в справке винды ([Win+F1]debug).

Теперь, запустим DEBUG и просмотрим, что у нас в регистрах. Вводим команду «R». Как видим, значение всех регистров процессора равняется нулю:

AX, BX, CX, DX = 0000

Мы можем вносить требуемые значения в регистры.

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#27 18-01-2011 19:39:28

Re: . Введение в Ассемблер

Пишем прогу на ассемблере.

Как уже говорилось, ассемблер — это самый низкий уровень программирования, который понимает проц. Теперь проведём эксперемент, чтоб убедиться в этом:

1) Создадим *.сом в программе DEBUG
2) Дизассемблируем его, при помощи того-же DEBUG
3) Полученные 16-тиричные значения и есть инструкции, которые выполняет процессор

Итак, начнём с создания *.сом, который выведет символ на экран. Запустим DEBUG и введём команду «А». Дальше, «топчем клаву» как на рисунке:

Чтоб вывести символ на экран, в регистр AH помещается 02H, а в DL — код выводимого символа, плюс 30H. Далее вызываем прерывание-DOS INT 21H (вывод на экран), и закрываем программу дёрнув прерывание INT 20H (exit). Всё, что находится после INT 20H игнорируется процессором.

В листинге дизассемблирования указывается сегмент памяти, в который была загружена наша программа (13F2) и смещение внутри сегмента 100H, обязательное для СОМ-файлов. Необходимо помнить, что прикладные программы загружаются в первую-свободную область памяти, поэтому у Вас значение 13F2 может быть другим, в зависимости от свободной памяти.

Следующим столбцом в дизассемблерном листинге идут 16-тиричные значения (выделены серым), которые представляют собой непосредственные инструкции процессору. Ниже — уже ничего нет, ..только ядро. Вообще-то есть ещё интерператор 16-тиричных чисел в двоичные, но он невсчёт. В конечном виде наша программа TEST_PROGA.COM обрабатывается процессором в таком вот виде:

Но вернёмся в реальность. Чтоже дают нам эти опыты. . а то, что программы написанные на ассемблере имеют наименьший размер, по сравнению с другими языками программирования. В качестве примера возьмём программу (окно с одной кнопкой в центре) написанную на языках высокого уровня. После компиляции получим такие размеры файла:

C++ Builder 4 — 22kb
Delphi 5 — 291kb
Delphi 5 + библиотека KOL — 26kb
Ассемблер MASM — около 3kb

Так, что смотрите и делайте выводы, что лучше использовать. Программу таких размеров можно легко внедрить в свободное пространство любого исполняемого файла. э-э-э чтот меня не туда занесло

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#28 19-01-2011 01:37:15

Re: . Введение в Ассемблер

..а вон чё WinHex показывает:

Да такой код можно хоть-куда пихнуть, ..к примеру в заголовок EXE-файла. Там столько свободного пространства, что можно слона разместить. 200-300h байт всегда найдётся. ..а нам больше и не надо, вешеприведённая TEST_PROGA.COM весит всего 17 байт (17 символов в исходнике). 300h — это уже 768 символов, ..целый материк, свобода мысли.

Достаточно перехватить управление в коде, перевести его на себя и замутить чё-нить. Объясню «в двух словах»: как это делается! ..Пишется прога на асме (желаемого характера), которая привычным движением руки вставляется в WinHex — в начало, середину, или «конец» EXE-файла жертвы. Желательно, конечно, в начало. после «PE»-заговка. Самый оптимальный вариант — после перечисления DLL-лок (инклудов). Там как-раз достаточно места, и быстрее примем управление. Фрагмент внедрения в CHKDSK.EXE нашей «Бацилы»:

Если Вы запустите такой инфицированный CHKDSK.EXE, то сначала отработает наш код, а только потом запустится сам chkdsk. . но не всё так просто. Там есть своя «Техника внедрения». Дизассемблируется chkdsk.exe, и в листинге ищется команда JMP (переход на метку). Перехватываем этот JMP и после исполнения основного кода «бацилы» передаём управление обратно на эту метку, командой RET ассемблера в коде нашей программы.

В качестве бонуса, вешаю в скрепке пару примеров программ на ассемблере.

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#29 19-01-2011 12:49:58

Re: . Введение в Ассемблер

Что нужно знать о прерываниях

Как уже отмечалось, прерывания бывают двух типов — DOS и BIOS. Но что они из себя представляют. Попробуем ответить на этот вопрос.

Прерывания — это вовсе не прерывания, а готовые программы (процедуры), которые компьютер вызывает для выполнения определенной задачи. Внутри этих «программ-прерываний» имеются вложенные подпрограммы, каждая из которых выполняет определённую задачу. Эти подпрограммы вызываются векторами прерываний!

Программа-прерывание вызывается по номеру (к примеру INT 13H, дисковый ввод/вывод BIOS), где в качестве «параметра» заносится её вектор, т.е. подпрограмма. Например, для вывода информации на экран, нам нужно воспользоваться сервисом-DOS и запросить прерывание с номером INT 21H. Подпрограмму 02H необходимо указать в регистре AH:

При включении компьютера, BIOS выстраивает таблицу векторов прерывания в первых 1024 байтах памяти. Этот килобайт памяти начинается с адреса 0000:0000 и заканчивается 0000:0400 (1024d = 0400h). Откроем в WinHex память, и взглянем на эту таблицу:

Каждый вектор имеет длину 4 байта. Вектор для прерывания 0 начинается с ячейки 0000:0000, прерывания 1 — с 0000:0004, 2 — с 0000:0008, 3 — с 0000:000C и т.д.

Если посмотреть на четыре байта, начиная с адреса 0000:0020, в которых содержится вектор прерывания 8H (прерывание времени суток), то Вы обнаружите там A5FE00F0. Имея ввиду, что младший байт слова расположен сначала, это 4-байтное значение переводится в F000:FEA5. Это стартовый адрес программы ПЗУ, выполняющей прерывание 8H.

Если размер таблицы 1024 байт, а один вектор имеет длинну 4 байта, то выходит чтобы найти общее кол-во векторов нужно 1024/4. . получаем 256. Таким образом, в общем пространстве имеется место для 256 векторов (подпрограмм), которые «разбиваются» по всем номерам прерываний BIOS и DOS. В каждом прерывании может находиться до 20 подпрограмм.

Прерывания с номерами до INT 20H обслуживает BIOS. Номера прерываний DOS лежат в пределах от 20 до 32H:

Прерывания BIOS (без подфункций) Прерывания DOS (без подфункций)

00h: Деление на ноль. 20h: Завершить программу
01h: Пошаговое. 21h: Сервис DOS
02h: Немаскируемое. 25/26h: Абсолютные чтение/запись диска
03h: Точка прерыв. 27h: Завершиться, но остаться резидентным
04h: Переполнение. 28h: Квант времени DOS (НЕТ В ДОКУМЕНТАЦИИ)
05h: Печать экрана. 2eh: Выполнить команду DOS (НЕТ В ДОКУМЕНТАЦИИ)
06h: (резерв) 2fh: Мультиплексное прерывание (спулинг печати)
07h: (резерв) 22h: Адрес завершения
08h: Таймер. 23h: Адрес Control-Break
09h: Клавиатура. 24h: Адрес обработчика критических ошибок
0Ah-0dh: (hdwr ints)
0Eh: Дискета.
0Fh: (hdwr int)
10h: Видео сервис.
11h: Список оборудования.
12h: Размер исп.памяти.
13h: Дисковый в/в.
14h: В/в последовательный порт
15h: Расшир.сервис AT.
16h: В/в клавиатуры.
17h: В/в принтера.
18h: ROM-BASIC.
19h: Загрузка.
1Ah: В/в таймера.
1Bh: Прерывание клавиатуры.
1Ch: Прерывание по таймеру
1Dh: Видео параметры
1Eh: Параметры дискет
1Fh: Символы графики

Приведу краткое описание прерывания-BIOS INT 13H:

INT 13H: дисковый ввод-вывод
Этот сервис предоставляет прямой доступ к адаптерам дискеты и жёсткого диска. Рекомендуется там, где это возможно, использовать INT 25H и INT 26H, чтобы предоставить драйверам устройств-DOS выполнять всю низкоуровневую обработку. Разумеется, для таких операций, как форматирование диска или установка защиты от копирования, прерывание INT 13H может оказаться единственной альтернативой.

подфункции: 00H сброс контроллера 08H дать парам диска 10H проверить готовность
01H дать статус 09H иниц табл парам 11H рекалибрация
02H читать секторы 0aH длинное чтение 14H диагностика
03H писать секторы 0bH длинная запись 15H дать тип диска
04H верификация 0cH искать цилиндр 16H изменить статус
05H форматир дорожку 0dH альтерн сброс 17H уст тип диска

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#30 20-01-2011 13:39:20

Re: . Введение в Ассемблер

Использование сервисов DOS. Прерывание INT 21H.

После загрузки MS-DOS в память, операционная система предоставляет нам свои услуги, в виде прерывания INT 21H (сервисы DOS). Используя это прерывание в своих программах мы можем выполнять около 80-ти операций. Не буду перечислять все функции этого прерывания, остановлюсь только на наиболее значимых:

00H: завершить программу 27H: читать блок произвольного файла
01H: ввод с клавиатуры 28H: писать блок произвольного файла
02H: вывод на дисплей 2aH: дать дату DOS
05H: вывод на принтер 2cH: дать время DOS
09H: Выдать строку 2fH: дать текущий DTA
0dH: Сбросить диск 30H: дать номер версии DOS
0eH: Выбрать умалчиваемый диск DOS 31H: завершиться и остаться резидентным — KEEP
0fH: открыть файл через FCB 32H: дать дисковую информацию DOS
10H: Закрыть файл через FCB 35H: дать вектор прерывания
13H: Удалить файл через FCB 36H: дать свободную память диска
14H: читать файл через FCB 39H: создать новое оглавление — MKDIR
15H: писать файл через FCB 40H: Писать в файл через описатель
16H: создать файл через FCB 48H: дать размер памяти
17H: Переименовать файл через FCB 56H: Переименовать/переместить файл
25H: установить вектор прерывания 5bH: создать новый файл

Функция 09H прерывания INT 21H (вывод строки символов на экран).

Процедуры, которые выводят целые строки символов на экран — очень полезны, но они могут накладывать ограничения на содержимое выводимой строки. Надо обращать внимание на то, какие управляющие коды (табуляция, пробел и т.п.) интерпретируются, а какие нет.

Как уже говорилось, при вызове прерывания необходимо указать значение функции в регистре AH (в нашем случае — 09H). Далее, вводятся инструкции и вызывается само прерывание. Регистр DX должен указывать на первый символ строки (т.е. расположение текстовой строки). В конце строки обязательно должен присутствовать символ «$». Это означает, что сам символ «$» не может входить в строку. Сама строка может быть любой длины.

Чтоб перевести текст на следующую строку, в конце указываются спец-символы 0AH (перевод строки), и 0DH (возврат каретки). Без них — текст будет располагаться в одну строчку.

. пришло время скачать инструментарий, чтоб проводить эксперементы. Программы, целиком написанные на ассемблере, транслируются в машинный код при помощи ассемблера. Под DOS-ом большой популярностью пользуется пакет TASM, для винды — MASM от Microsoft. С ним конкурирует FASM, поддерживающий более естественный синтаксис. Его и качаем с сайта WASM.RU. Он отличается от предшественников тем, что это и транслятор и компилятор в одном флаконе. Вводиш в окне инструкции, жмёш F9 и на выходе получаеш готовый исполняемый файл! Очень удобно. особенно для начинающих!


. значит скачали FASM 1.67, и в поле набиваем текстовые строки нашей программы. Вот пример:

Программа, приветствующая WHATIS из досовского окна.

use16 ; DOS работает в 16-тиразрядном режиме
org 100h ; Делаем СОМ-файл с начальным смещением 100h

mov AH,09h ; Суём в регистр AH функцию 09h прерывания 21h
mov dx,text ; В регистре DX указываем от куда брать строку
int 21h ; Вызываем прерывание 21h
ret ; Возвращаемся туда, от куда были вызваны

; Текстовая строка (адрес для регистра DX)
text db ‘Hello, WHATIS. $’

. если нужно вывести несколько строк, то можно сделать так:

. на выходе — СОМ-файл размером 63 байт. Таким способом можно выводить текстовые строки из памяти, которые содержат информацию об оборудовании, объёме свободной памяти и т.д. и т.п.

Программа составляется из нескольких-подобных участков кода, которые выполняют определённые задачи. На каждый участок кода ставится индивидуальная метка, к которой можно обратиться с любого места программного кода. Эти участки объединяются в модули, а несколько модулей образуют законченный софт, . в чём мы убедимся позже.

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#31 21-01-2011 12:22:44

Re: . Введение в Ассемблер

Определение Стека

Стек — это такое место хранения данных, которые при надобности можно обратно восстановить. В нём хранятся адреса переходов, различные данные и т.д. Регистр SP указывает на адрес вершины стека. Регистр ВР содержит адрес, начиная с которого в стек вносится или забирается информация.

Представьте, что одна подпрограмма вызывает другую. Вызываемая подпрограмма завершила свое выполнение, теперь ей надо передать управление подпрограмме, которая её вызвала. Как-раз адрес следующей команды (после вызова подпрограммы) находится на верхушке стека, в регистре SP.

Стек — как штанга с блинами: засунули адрес, засунули второй, засунули третий, и достают адреса в порядке обратном засовыванию, ..сначала третий, второй, первый. Следовательно, подпрограмма, может вызвать ещё одну подпрограмму, а она в свою очередь ещё одну и так, сколько хошь, всё ограничивается только размером стека.

Таким образом, программа продолжит выполнение инструкций только после того, как отработают ПОДпрограммы, принявшие управление:

В стек можно заносить не только адреса, но и данные, текстовые строки и т.п. Команда ассемблера PUSH помещает данные в стек, а команда POP снимает их от туда. При использовании стека наша программа «Hello, Whatis. » примет следующий вид:

Здесь, мы закинули в стек вторую строчку текста, вывели на экран первую, а потом извлекли из стека вторую. Дело в том, что регистр не может хранить сразу два разных значения, поэтому перед тем как внести в него, нужно сохранить имеющееся, дабы не потерять всё.

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

#32 24-01-2011 12:34:02

Re: . Введение в Ассемблер

Память 16-тиразрядных систем (DOS).

Самое главное преимущество ассемблера состоит во взаимодействии с памятью. Программировать на ассемблере не зная, как устроена память — бессмысленно.

В DOS — память сегментная. Вся память делится на сегменты по 64К, и адрес задаётся форматом «сегмент:офсет». Сегмент — задаёт порядковый номер сегмента, а офсет — смещение в этом сегменте. Это объяснение для 16-тиразрядных программ (32-хразрядные обсудим позже).

На рис. общая память, разделённая на сегменты по 64kb. Здесь — максимум 65536 сегментов:

;; 16 двоичных разрядов — это 1111 1111 1111 1111, или 65535d (FFFFh).
;; 65535 * 64Кб = 4 194 240Кб (или 4096Мб, или 4Гб памяти).

С помощью 16 бит можно адресовать только 65536 байт памяти и 65536 сегментов. Например, 0000:4012 это означает: сегмент 0, смещение 4012. Чтобы узнать, что находится в том адресе, вы сначала переходите на сегмент 0, а затем в сегменте смещаетесь на 4012.

Память 32-хразрядных систем (WIN-32).

В 32-хразрядном Windows (95 и выше) Вы всё еще имеете сегменты, но вам не нужно заботиться о них, потому, что они уже не 64kb (как в 16-разрядном), а 4 Гб. Это называеся плоской моделью памяти (flat). Здесь есть только смещения и они теперь 32-разрядные (в диапазоне от 0 до 4 294 967 295). Каждая ячейка в памяти указывается смещением.

Но 4ГБ может и не быть на машине, поэтому эта память называется виртуальной. Мало того, каждый процесс выполняется в своём виртуальном адресном пространстве, . а это значит, что никакой другой процесс не сможет получить доступ к вашей памяти. Для этого существуют специальные API функции.

Память 0-0000FFFF не используется и служит для выявления нулевых указателей, значит, если вы укажете адрес 0000С567, то он будет считаться нулевым. Любая попытка обратится к этой памяти приводит к ошибке. Память выше 80000000 одна для всех процессов. В этой памяти находится код нулевого кольца, структуры ядра, код планировщика задач, код драйверов, диспетчер ввода вывода, таблица прерываний и т.д. Любая попытка обратиться к памяти ядра приводит к ошибке и к немедленному завершению приложения.

Память в диапазоне 00001000-7FFFFFFF доступна для 3 кольца (т.е. для вашего приложения). С ней Вы, что хотите то и делаете, в неё также грузятся DLL-ки.

Если Вам даётся 2ГБ памяти, то это не означает, что вы можете обратиться к любому участку памяти. Для того чтобы получить доступ к некоторому участку памяти надо сначала её зарезервировать. Минимальный размер выделяемой памяти — страница, равна 1000h байтам (1000h байт = 4096d байт, или 4КБ). Даже если вы захотите выделить 5 байт, то всё равно выделится 4КБ. Думаю, вы не столкнётесь с тем, что вам надо будет выделять память. Это нужно при работе с файлами для того, что бы в эту память читать файл.

Болтовня ничего не стоит. Покажите мне код.. (Linus Torvalds)

Dos fn 10h: закрыть файл через fcb

Ассемблер? Это просто! Учимся программировать (FAQ)
______________________________________

Вопросы, которые поступили от подписчиков рассылки
«Ассемблер? Это просто! Учимся программировать»

Дата выхода: 2001-08-16

Здравствуйте!
Значит, история такая: мой приятель купил винт Quantum AS на 10 гигов. И принёс мне — временно, пока он не купит все остальные части компа. А у меня его не видно.
BIOS-то этот винт детектит, а вот Виндоуз — ни в какую. Я джамперы и так и сяк ставил — безуспешно.
Быть может, дело в моей матплате Acorp для Pentium MMX ?
Она у меня старая, 1997 года. Если так, то мне перед тем, как тоже винт покупать, и матплату сменить? (А заодно и процессор, и корпус с AT на ATX. )
Кстати, какую лучше брать матплату для Дюрона?
Спасибо за внимание.
Константин.

Привет!
А ты его отформатировал? Если нет, то вначале иди запускай fdisk, создавай логические диски, а потом форматируй их с помощью
format disk:
Если хочешь, чтобы весь диск можно было одним куском отформатировать в программе fdisk надо согласиться на поддержку больших дисков( >2ГБ).

Отправил эксперт: Александр
Эксперт отправил ответов (всего): 65

Экспертная группа: Модели, виды и типы компьютеров (hard)

Пишу программу работающую в реальном режиме времени
Использую прерывание по таймеру
Основная программа пишется на Паскале (Borland Pascal 7.0)
Иницилизация таймера и обработка прерывания на ассемблере.
В обработке прерывания работа с lpt-портом. И. проблема :
добавление команд out dx,al (время выполнения по некоторым
данным на 486 машине — 10 тактов, а у меня Celeron 433) приводит к изменению промежутка времени между прерываниями. Я в шоке! Помогите — горит проект и меня ждет жестокая расправа.
Ниже привожу исходник.

Не знаю, что у меня хорошего получилось, но лучше, думаю, сделать так (см. приложение, там все написано).

Отправил эксперт: Василий
Эксперт отправил ответов (всего): 20

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Здравствуйте, Broken Sword, уважаемые эксперты,

_программа_ должна трассировать Int 21h и сама принимять решение о местонахождении заданной функции.
Весь процесс проходит _автоматически_ без человеческого вмешательства.

Ко всему, возможно, добавляются защиты от трассировки, вроде уничтожения векторов 1 и 3, проверка и подмена флагов трассировки, запись «мусора» в регистры TR1, TR2 . и т.д.

С нетерпением жду ответа,
Андрей.

Не понял, ты хочешь, чтобы я тебе такую программу написал или у тебя есть идеи, но требуются консультации?

Отправил эксперт: Василий
Эксперт отправил ответов (всего): 21

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

У меня проблема с завершением работы Windows98, мне приходится два раза повотрять операцию «Выключить компьютер». Каким образом мне изабивться от этого глюка?

Здравствуйте, Владимир!
Могу сходу предложить три варианта действий:
1.Проверить машину стандартным regclean-ом (можно взять на download.com.
2.Проверить машину с помощью приблуды типа Нортон Виндоктор.
Если ошибка была связана со сбоем в реестре — должно помочь.
3.Вариант, связанный с запуском приложения типа AVX ICQ checker.
(Мне также приходится по два раза выключаться, после первого раза он выкидывает aqmon, после второго — собственно выключается.Но если пользуешься ICQ и не хочешь заловить вируса луче перестраховаться, не так ли =|;о) ).

Отправил эксперт: RANDOM
Эксперт отправил ответов (всего): 10

Экспертная группа: Пользовательская работа с Windows

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

Описание: CX байт данных записывается в файл или на устройство с описателем,
заданным в BX. Данные берутся из буфера, адресуемого через DS:DX.
Данные записываются, начиная с текущей позиции указателя
чтения/записи файла.

Используйте функцию 42H LSEEK, чтобы установить указатель файла,
если необходимо (OPEN сбрасывает указатель в 0).

Обновляет указатель чтения/записи файла, чтобы подготовиться
к последующим операциям последовательного чтения или записи.

Вы должны всегда сравнивать возвращаемое значение AX (число запи-
санных байт) с CX (запрошенное число байт для записи).
если AX = CX, запись была успешной
если AX Эксперт отправил ответов (всего): 22

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Здравствуйте!
Значит, история такая: мой приятель купил винт Quantum AS на 10 гигов. И принёс мне — временно, пока он не купит все остальные части компа. А у меня его не видно.
BIOS-то этот винт детектит, а вот Виндоуз — ни в какую. Я джамперы и так и сяк ставил — безуспешно.
Быть может, дело в моей матплате Acorp для Pentium MMX ?
Она у меня старая, 1997 года. Если так, то мне перед тем, как тоже винт покупать, и матплату сменить? (А заодно и процессор, и корпус с AT на ATX. )
Кстати, какую лучше брать матплату для Дюрона?
Спасибо за внимание.
Константин.

Здравствуйте, Константин!
Просто напросто у тебя жёсткий диск новый, поэтому на нем нет никакой файловой системы(для Win — обычно Fat 32, для Пингвина — Ext2+Swap).
Тебе надо найти FDisk(стандартная для Win) или Partition Magic, затем создать основной раздел дос на нём(или ещё дополнительный), тогда всё будет в порядке.
А, вообще, обычно к жёсткому диску при покупке должна прилагаться дискета с утилитой установки жесткого диска!

Отправил эксперт: Orlando
Эксперт отправил ответов (всего): 10

Экспертная группа: Модели, виды и типы компьютеров (hard)

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

Здравствуйте, fagot!
По первому вопросу читай выпуск 056 этой рассылки, там есть как найти серийный номер винта(и дискеты соответственно)
По второму вопросу
Для открытия функция 3dh
al=Access mode(0-read, 1-write, 2-both)
DS:DX=ASCIIZ строка полного пути файла
Выход
если бит С=1 AX=Error code, иначе AX=Handle
Тогда для записи используем ф-цию 40h
AX=40h
BX=Handle
CX=кол-во байт для записи
DS:DX-адрес буфера
Выход
если бит С=1 AX=кол-во реально записанных байт

Отправил эксперт: Sensey
Эксперт отправил ответов (всего): 76

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Здравствуйте!
Значит, история такая: мой приятель купил винт Quantum AS на 10 гигов. И принёс мне — временно, пока он не купит все остальные части компа. А у меня его не видно.
BIOS-то этот винт детектит, а вот Виндоуз — ни в какую. Я джамперы и так и сяк ставил — безуспешно.
Быть может, дело в моей матплате Acorp для Pentium MMX ?
Она у меня старая, 1997 года. Если так, то мне перед тем, как тоже винт покупать, и матплату сменить? (А заодно и процессор, и корпус с AT на ATX. )
Кстати, какую лучше брать матплату для Дюрона?
Спасибо за внимание.
Константин.

Здравствуйте, Константин!
Кажись ты прав- твоя мать видит винты до 8 гиг
Хотя! Попробуй его на отдельный шлейф, причем строго Primary Master
А загружайся с другого, то есть типа с D
Для Дюрона лучше всего Soltek, хотя Canyon лучше, но дороже
И не пожалей лишних 3$ на корпус, возьми CodeGen- он пошире, охлаждение получше, и Дюрон с хорошим вентилятором точно влезет.

Отправил эксперт: Sensey
Эксперт отправил ответов (всего): 77

Экспертная группа: Модели, виды и типы компьютеров (hard)

с ЛЕМЪ РЮЙЮЪ ОПНАКЕЛЮ. лЮРЕПХМЯЙЮЪ ОКЮРЮ Asus CUEP2-M. мЮЯРПНИЙХ ОН СЛНКВЮМХЧ ГЮБНДЯЙХЕ. оНД DOCНЛ (МЕ ГЮЦПСФЮЪ Windows) Ъ МЕ БХФС ЛШЬЭ Х ХМНЦДЮ ОПНОЮДЮЕР ЙКЮБХЮРСПЮ. щРН ВРН МЕХЯОПЮБМНЯРЭ ЛЮРЕПХ ХКХ ЦДЕ-РН Ъ МЕСЯКЕДХК, МН МЮЯРПНИЙХ РН ГЮБНДЯЙХЕ. (Х ОНРНЛ МЮЯЙНКЭЙН Ъ ГМЮЧ ЛШЬЭ Х ЙКЮБХЮРСПЮ МХЙЮЙ МЕМЮЯРПЮХБЮЧРЯЪ Б BIOS). нОЕПЮЖХНММСЧ ЯХЯРЕЛС ОЕПЕЯРЮБХК, ПЮГЗЕЛШ ЛШЬХ Х ЙКЮБХЮРСПШ PS/2

гДПЮБЯРБСИРЕ, юКЕЙЯЕИ!
хГБХМХРЕ ГЮ БЯРПЕВМШИ БНОПНЯ, Ю бШ ДПЮИБЕП ДКЪ ЛШЬХ СЯРЮМЮБКХБЮКХ?
ю ЙКЮБХЮРСПЮ ХМНЦДЮ РЮЙ ЯЕАЪ БЕДёР.

Отправил эксперт: яРЮЯ
Эксперт отправил ответов (всего): 6

Экспертная группа: лНДЕКХ, БХДШ Х РХОШ ЙНЛОЭЧРЕПНБ (hard)

КАК
МОЖНО
ПОЛУЧИТЬ
ВСЮ
рассылку с начала.
Чтобы не повторять вопросы
не отнимать время
и неказаться совсем глупым

С уважением к Твоей просветительной деятельности
Олег

Олег Никуленков!
http://www.kalashnikoff.ru/, ссылка Ассемблер, там архив — ВСЕ номера рассылки «Ассемблер, это просто», и 33 (помоему) FAQ из 60 полных, все FAQ можно получить токо осенью

Отправил эксперт: Broken Sword
Эксперт отправил ответов (всего): 51

Экспертная группа: Общие вопросы по программированию на Ассемблере под Win32

гДПЮБЯРБСИРЕ, СБЮФЮЕЛШЕ ЩЙЯОЕПРШ.
мЕДЮБМН С МЮЯ КНЙЮКЭМСЧ ЯЕРЭ ОПНРЪМСКХ. яПЮГС ФЕ БНГМХЙКЮ ОПНАКЕЛЮ, Р.Й. Ъ ПЮАНРЮЧ ХГ ОНД ДБСУ НЯЕИ — WinXP RC2 Х Win98. рЮЙ БНР, ЯСРЭ ОПНАКЕЛШ Б РНЛ, ВРН ХГ ОНД БХМ98 БЯё МНПЛЮКЭМН ПЮЯЬЮПХБЮЕРЯЪ, БЯё ОНКЭГНБЮРЕКХ ОЮОЙХ БХДЪР, Б МЕЙНРНПШЕ ЛНЦСР ОХЯЮРЭ ЦДЕ ПЮГПЕЬЕМН, Ю ОНД WinXP ОНВЕЛС РПЕАСЕРЯЪ ОЮПНКЭ ОПХВЕЛ Й ОЮОЙЕ IPC$. лНФЕР ЩРН МЕДНДЕКЙХ ЙЮЙХЕ, БЕДЭ НТХЖХЮКЭМНЦН ПЕКХГЮ ЕЫЕ МЕ БШЬКН. ю ЛНФЕР БЯё-РЮЙХ ЛНФМН ЙЮЙ-МХАСДЭ МЮЯРПНХРЭ ?
P.s. вРН-РН ОНУНФЕЕ МЮАКЧДЮЕРЯЪ Х Я Win2000 Professional SP1.
я СБЮФЕМХЕЛ, дЛХРПХИ.

гДПЮБЯРБСИРЕ, дЛХРПХИ!
б НОЕПЮЖХНМЙЮУ НЯМНБЮММШУ МЮ NT (NT 4.0, w2k, winXP) ОПХЛЕМЪЕРЯЪ ДПСЦЮЪ ЯХЯРЕЛЮ ОПНБЕПЙХ ОНКЭГНБЮРЕКЪ. р.Е. ВРНАШ ОНКСВХРЭ ДНЯРСО Й ПЮЯЬЮПЕМНЛС ПЕЯСПЯС МЕНАУНДХЛН ББНДХРЭ МЕ РНКЭЙН ОЮПНКЭ МН Х КНЦХМ. ЩРН ЛНФМН ОПХ ОНЛНЫХ ЯОЕЖХЮКЭМНИ ОПНЦПЮЛЙХ (e.g. Essential NetTools ЙНЛОЮМХХ «TamosSoft» www.tamos.com), КХАН МЮДН КНЦХМХРЭЯЪ Б win’9x Я ХЛЕМЕЛ Х ОЮПНКЕЛ ОНКЭГНБЮРЕКЪ ЙНРНПНЛС МЮ WinXP ПЮГПЕЬёМ ДНЯРСО Й ПЮЯЬЮПЕМНЛС ПЕЯСПЯС.
ю КСВЬЕ ОНЯРЮБЭРЕ ЯЕПБЕП, ОСРЮМХЖШ АСДЕР ЛЕМЭЬЕ.

Отправил эксперт: яРЮЯ
Эксперт отправил ответов (всего): 8

Илон Маск рекомендует:  Что такое код cpdf_set_title

Экспертная группа: оНКЭГНБЮРЕКЭЯЙЮЪ ПЮАНРЮ Я Windows

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

Уважаемый fagot! Вот пример проги, замени ‘Текст’
text_mes db ‘Текст’ на любой свой, и придумай имя файла
filename db ‘c:\text.txt’,0

Отправил эксперт: Broken Sword
Эксперт отправил ответов (всего): 52

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Здравствуйте!
У меня усть вопросики :)
1) Где можно найти tasm32.exe, tlink32.exe & import32.lib
2) Сейчас я пользуюсь Масмом, но у меня есть проблемка с созданием экзешника вот, то что я делаю.
файл Digger.asm:

includelib c:\masm\lib\kernel32.lib
extrn _imp_ExitProcess@4:dword
ExitProcess equ _imp_ExitProcess@4

.386
.model flat,stdcall
option casemap:none
.data
;Инициализированные данные
.data?
;Неинициализированные данные
.code
start: ;Точка входа

push 0
call ExitProcess ;Выход из программы
end start
—————-
А потом я запускаю.
masm /Ic:\masm digger.asm
link digger.obj,digger.exe
—————-
Выводиться сообщение об шибке.
Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992
Copyright (C) Microsoft Corp 1984-1992. All rights reserved.

List File [nul.map]:
Libraries [.lib]:
Definitions File [nul.def]:
LINK : warning L4021: no stack segment

digger.obj(digger.asm) : error L2029: ‘_IMP_EXITPROCESS@4’ : unresolved external

There was 1 error detected
———————-
Может я неправильно создал kernal32.lib.
НО kernal32.lib от Visual C++ не подошёл.
ии я сделал
implib.exe kernal32.lib kernal32.dll
(предварительно скопировав dll в ту директорию где запускал implib :)

Я думаю что это связано с ограничением длинны имен, которое присутствует в некоторых объектных файлах.

Или (что вернее) в данном случае у тебя просто отсутствует глобальная переменная _imp_ExitProcess@4

Или же masm все имена приводит к нижнему регистру.

Или же все вместе. :) не знаю точно.

Отправил эксперт: Dron (http://spawnhole.narod.ru/asmos/asmos.html — Операционная система с нуля!)
Эксперт отправил ответов (всего): 53

Экспертная группа: Работа с MASM/TASM

А существуют ли разные всякие ассемблерные библиотеки? Где их можно поискать? (может есть сайты специальные?) Мне например нужен оконный интерфейс для ассемблерной проги. Не как Turbo Vision конечно, поскромнее, но желательно готовый.
PS прилиновать TV не предлогайте :)

Ну и обленился же ты!
Самому состряпать слабо?! Можно даже, используя объекты, благо TASM их поддерживает. Могу если что с этим помочь.

Отправил эксперт: Василий
Эксперт отправил ответов (всего): 23

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Здравствуйте,уважаемые эксперты. ) :)
Ответьте, пожалуйста вот на такой вопрос:)как создать файл, что-нить записать в него, удалить файл с диска, памяти, переместить файл, скопировать?

Здравствуйте, Веселый Эдик!

Как много ты сразу хочешь знать.

Обрати свое внимание на следующие функции DOS:

int 21h
fn 3ch Create file via handle
fn 3dh Open file via handle
fn 3eh Close file via handle
fn 3fh Read from file via handle
fn 40h Write to file via handle
fn 41h Delete file

Функции копирования файлов в досе не существует. реализуется через чтение/запись.

Помимо функций, работающих черех handle есть еще функции работающие через FCB, ноони гораздо неудобнее!.

Отправил эксперт: Dron (http://spawnhole.narod.ru/asmos/asmos.html — Операционная система с нуля!)
Эксперт отправил ответов (всего): 54

Экспертная группа: Общие вопросы по программированию на Ассемблере под DOS

Подписаться на рассылки


Форма подачи вопроса

ВНИМАНИЕ. Пожалуйста, НЕ высылайте один вопрос сразу нескольким подгруппам! Дополнения к вопросам, на которые эксперт уже ответил НЕ следует направлять ведущему рассылки (я не успеваю!). Просто скомбинируйте первый вопрос и дополнение к нему, а затем заново отправьте его, используя приведенную ниже форму!

Нажимайте кнопку «Отправить» только ОДИН раз и дождитесь полной загрузки страницы, иначе вопрос будет продублирован!

Ведущий рассылки,

По вопросам сотрудничества, рекламы и спонсорства обращайтесь:

Группа дисковых функций MS-DOS

В эту группу входят прерывания, предназначенные для выполнения основных функций операционной системы, в том числе для выполнения операций с логическими дисками, файлами и каталогами [3, 10]. Дисковые функции DOS обладают достаточной полнотой и универсальностью для решения любых задач в реальном режиме DOS. Они могут применяться и в режиме линейной адресации памяти, но информацию в расширенную память приходится пересылать через промежуточный буфер в первом мегабайте адресного пространства процессора. Впрочем, дополнительные пересылки не особенно замедляют работу: поиск данных на диске и передача информации между диском и процессором занимает гораздо больше времени, чем копирование такого же объема данных с одного участка оперативной памяти в другой.’

Ниже описаны функции DOS, выполняющие основные операции над логическими дисками, каталогами и файлами. При описании используются следующие термины:

• строка ASCIIZ — текстовая строка в ASCII-коде, которая завершается нулевым значением;

• дескриптор файла — уникальный номер, который операционная система присваивает создаваемому или открываемому файлу в качестве идентификатора (чтобы потом обращаться к файлу по этому номеру вплоть до его закрытия).

Классические функции для работы с дисками

К этой группе относятся функции, появившиеся в ранних версиях операционной системы MS-DOS и сохранившиеся с тех пор практически без изменений. Такие функции отличаются крайне примитивной обработкой ошибок:

• в случае успешного завершения операции флаг CF сбрасывается в 0;

• в случае ошибки флаг CF устанавливается в 1.

Для обращения к дисковым функциям DOS используется прерывание Int 21h.

Прерывание Int 21 h, функция OEh: сменить текущий логический диск

Функция позволяет выбрать логический диск. Перед вызовом прерывания требуется записать в регистры следующие значения:

• в АН — значение OEh;

• в AL — код логического диска (0 — А:, 1 — В: и т. д.).

После завершения операции функция возвращает в регистре AL максимально возможный в данной системе номер логического дисковода (определяется параметром LASTDRIVE в файле CONFIG.SYS).

Прерывание Int 21 h, функция 19h: определить номер текущего дисковода

Функция определяет номер дисковода, который в данный момент считается текущим, то есть используется по умолчанию.

Перед вызовом прерывания требуется записать в регистр АН значение 19h.

После завершения операции функция возвращает в регистре AL код логического диска (0 — А:, 1 — В: и т. д.).

Прерывание Int 21 h, функция 1Ah: изменить адрес области обмена с диском

Функция устанавливает адрес буфера, используемого в операциях ввода-вывода и поиска в каталогах.

Перед вызовом прерывания требуется записать в регистры следующие значения:

• в АН — значение lAh;

• в DS: DX — указатель на новый адрес буфера обмена DTA. ПРИМЕЧАНИЕ

При запуске программы ее область DTA первоначально установлена по адресу PSP:0080h.

Прерывание Int 21 h, функция 2Fh: получить адрес области обмена с диском

Функция определяет текущий адрес буфера, используемого в операциях ввода-вывода и поиска в каталогах.

Перед вызовом прерывания требуется записать в регистр АН значение 2Fh.

После завершения операции функция возвращает в ES: ВХ указатель на адрес буфера обмена DTA.

Прерывание Int 21 h, функция 36h: определить объем свободного места на диске

Функция определяет объем свободного места на заданном логическом диске.

Перед вызовом прерывания требуется записать в регистры следующие значения:

• в АН — значение 36h;

• в AL — код логического диска (0 — А:, 1 — В: и т. д.).

В случае ошибки в регистре АХ будет возвращен код OFFFFh (недопустимый код логического диска).

В случае успешного завершения операции функция возвращает:

• в АХ — число секторов в кластере;

• в ВХ — число свободных кластеров;

• в СХ — число байтов в секторе;

• в DX — полное число кластеров на диске.

Объем свободного пространства определяется произведением содержимого регистров АХ, ВХ и СХ, а полный объем диска в байтах — произведением АХ, СХ и DX.

Улучшенные функции для работы с дисками

По мере развития MS-DOS в набор функций постоянно вносились дополнения, упрощающие выполнение тех или иных операций и улучшающие контроль за их выполнением. Для вызова функций данной группы также используется прерывание Int 21h.

Перечисленные ниже функции DOS имеют усовершенствованные средства контроля: в случае ошибки, кроме установки флага CF, выдают в регистре АХ код ошибки, по которому можно определить причину ее возникновения. Возможные значения кодов ошибок приведены в табл. 6.1. Однако следует учитывать, что содержимое регистра АХ в случае успешного завершения данных функций не сохраняется.

Таблица 6.1. Значения расширенных кодов ошибки

Dos fn 10h: закрыть файл через fcb

Создание программ на языке Assembler.

[администратор рассылки: Лысков Игорь Витальевич (Старший модератор)]

Лучшие эксперты в этом разделе

Коцюрбенко Алексей Владимирович
Статус: Модератор
Рейтинг: 1154
Зенченко Константин Николаевич
Статус: Старший модератор
Рейтинг: 457
solowey
Статус: Бакалавр
Рейтинг: 235
Перейти к консультации №:

Здравствуйте уважаемые эксперты! Помогите пожалуйста с ответами на вопросы(на некоторые я попробую
ответить, а ответы на остальные честно говоря не знаю, по возможности поправьте меня пожалуйста):

1. Какие в MS-DOS есть способы обращения к файлам. (Насколько я понимаю — это обращения к записям и
если это так, то существуют два способа: последовательный и произвольный).

2. Какие существуют методы управления файловыми функциями.
(Я знаю только метод управления с помощью описателя и где-то читал о FCB, но я не знаю, что это такое. )

3. Как организовать прямой доступ к файлу, используя Handle-ориентированные функции обслуживания файлов.
(при создании, открытии или удалении файла в DS:DX мы помещаем путь к файлу и его имя, а в остальных функциях просто помещаем в BX описатель, т.е Handle файла, который был получен после создания/открытия файла.

4. Как организовать работу с устройствами ввода-вывода, кроме дисков, используя файловые функции. (?)

5. Что такое указатель файла и какие существуют функции для работы с ним.
(не знаю как по умному написать, что такое указатель, а для работы с ним используется функция 42h,
но с ней чесно говоря ещё не работал)

6. Как определить размер файла на диске. (?)

Состояние: Консультация закрыта

Здравствуйте, Николай // Programmator .
мой ответ будет такой
1. К файлу можно обращаться с помощью имени, полного имени, спецификации. подробнее например URL >>пример
2. через описатель и через FCB. подробнее URL >>FCB
3. сами ответели
4. через чтандартные описатели 3-AUX (COM1-обычно), 4-PRN (LPT1-обычно)
5. число, номер который идентифицирует структуру внутри ОС для работы с файлом (42р + открытие и закрытие тоже)
6. вызвать функцию 42h c AL=2, CX:DX=0:0 получите длину

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Здравствуйте, Николай // Programmator .

(2)
В DOS есть 2 группы функций для работы с файлами:
— через FCB (File Control Block) — устаревшие, забудьте о них, как о страшном сне;
— Handle-ориентированные (современные)

(1)Последовательный и произвольный доступ, (5) указатель файла.
Насколько я понимаю, Вы имеете в виду указатель текущей позиции файла (read/write pointer). А указатель файла — иногда так называют описатель файла (handle).

После открытия/создания файла указатель текущей позиции устанавливается на начало файла, каждая операция ввода/вывода продвигает его на соответствующее кол-во байт вперед (к концу файла). Иначе говоря, чтение и запись файла осуществляется начиная с текущей позиции, по окончании указатель продвигается на записанное/прочитанное кол-во байт. Указатель текущей позиции можно передвигать с помощью функции LSEEK (AH=42h).

После того, как Вы открыли файл, все операции осуществляются последовательно, если только Вы не перемещаете указатель текущей позиции файла. Таким образом, в DOS только от Вас зависит, как обращаться к файлу — последовательно (не меняя текущую позицию с помощью ф-и LSEEK) или произвольно — устанавливая перед операцией текущую позицию в требуемое значение.

(3)
— Открываете (AH=3Ch) или создаете (AH=3Dh) файл, получаете описатель (handle) файла в регистре AX, запоминаете его где-нибудь. Если CF=1, то произошла ошибка.
— читаете (AH=3Fh)/пишете (AH=40h) файл.
— функция lseek (AH=42h) позволяет переместить указатель текущей позиции в произвольное место файла.
— закрываете файл (AH=3Eh)

(4) стандартные описатели (handle) устройств:
0 — стандартное устройство ввода (обычно, клавиатура)
1 — стандартное устройство вывода (обычно, экран)
2 — стандартное устройство вывода ошибок (всегда — экран)
3 — стандартное последовательное устройство (COM1)
4 — стандартный принтер (LPT1)

(6) для определения размера файла переместите указатель текущей позиции в конец:

; определяем длину файла
mov ax,4202h ; AL = 2 — смещение задается от конца файла
mov bx,[hFile]
xor cx,cx ; CX:DX — смещение от конца файла = 0
xor dx,dx
int 21h
jc _lseek_error
; на выходе DX:AX — новая текущая позиция от начала файла. В данном случае — размер файла
mov word ptr [nFileSize],ax
mov word ptr [nFileSize+2],dx

Dos fn 10h: закрыть файл через fcb

Представленная ниже страница, лишь часть огромного сайта посвященного различной компьютерной документации, на сайте собрано более 800 мб информации. Если Вы не нашли в этой статье, то что Вы ищите попробуте посмотреть здесь, cпросить на форуме или поискать необходимую Вам информацию в нашем каталоге ссылок сайтов компьтерной тематики.

Если же Вы хотите приобрести бумажную копию представленных здесь
материалов, обращайтесь в наш книжный магазин.

С уважением,
команда разработчиков eManual.ru

3. Файловая система DOS

Теперь, после того, как мы познакомились с логической структурой диска в MS-DOS, можно приступить к изучению одной из самых развитых подсистем операционной системы — файловой системы.

Сервис файловой системы доступен программе через прерывание MS-DOS INT 21h . Многочисленные функции этого прерывания, относящиеся к файловой системе, можно разбить на группы:

  • получение справочной информации;
  • работа с каталогами;
  • работа с файлами.

Функции первой группы позволяют программе получить разностороннюю информацию, касающуюся текущего состояния дисковой подсистемы — текущие используемые диск и каталог, размер свободного места на диске, параметры логического диска и т.д.

Функции второй группы выполняют все необходимые операции с каталогами — создание, переименование, уничтожение каталогов, изменение текущего каталога и т.д.

Третья группа функций позволяет программе выполнять практически любые операции над файлами — создание, удаление, чтение/запись, переименование, копирование, пересылка и т.п.

Заметим, что существует два класса функций для работы с файлами. Первый класс использует управляющие блоки файлов FCB . Эти функции исплоьзовались в MS-DOS версий 1.х и имеют в настоящее время чисто исторический интерес. Вам они скорее всего никогда не будут нужны, за исключением одного случая — если вам надо составить программу, способную работать под управлением MS-DOS версии 1.0 или 1.1. В этой книге мы не будем упоминать функции, предназначенные для работы с файлами через FCB . При необходимости вы сможете найти информацию об этих функциях в руководстве по операционной системе MS-DOS.

Второй класс использует файловые индексы (handle). Этот класс функций впервые появился в MS-DOS версии 2.0. Эти функции аналогичны используемым в операционной системе UNIX.

Смысл файлового индекса очень прост. Для того чтобы начать работу с файлом, программа должна вызывать определенную функцию DOS, «открывающую» этот файл. Процесс открытия файла заключается в присвоении этому файлу определенного числа (индекса) и выполнении некоторых других инициализирующих действий. Для выполнения каких-либо операций с файлом программа, вызывая соответствующую функцию MS-DOS, должна указать индекс этого файла.

Первые пять файловых индексов зарезервированы операционной системой:

Стандартное устройство ввода (клавиатура)
1 Стандартное устройство вывода (экран)
2 Стандартное устройство для вывода сообщений об ошибках (экран)
3 Стандартное устройство последовательного ввода/вывода, обычно это асинхронный адаптер COM1 .
4 Стандартное печатающее устройство (обычно первый принтерный порт LPT1 )

Зарезервированные файловые индексы всегда доступны программе. Для устройств, соответствующих этим индексам, не требуется выполнять операцию открытия.

Одно из преимуществ второго класса файловых функций — возможность одновременной работы с файлами, находящимися в разных каталогах.

Состав функций MS-DOS, предназначенных для работы с файловой системой, достаточно разнообразен и функционально полон. Только в очень редких случаях, связанных в основном с организацией защиты информации от несанкционированного доступа, вам может потребоваться доступ к диску на более низком уровне. Если ваша программа использует для работы с файлами только документированные функции операционной системы, ее работа не будет зависеть от аппаратных средств компьютера, от используемой для создания разделов диска утилиты.

Описание функций MS-DOS, предназначенных для работы с файловой системой, мы начнем с функций получения справочной информации.

Прежде чем мы начнем обзор функций получения справочной информации о состоянии и параметрах дисковой подсистемы, введем понятие текущего диска и текущего каталога.

Если вы запускаете программу, которая находится в каком-либо каталоге на одном из дисков, то эти диск и каталог становятся текущими для MS-DOS. Это можно понимать в том смысле, что программе не требуется каждый раз при работе с файлами указывать требуемый диск или каталог.

В любой момент времени программа может узнать текущие диск или каталог, а также заменить их. Для этого она должна использовать специальные функции прерывания INT 21h.

Для установки текущего диска можно использовать функцию 0Eh , которая имеет следующий формат вызова:

На входе: AH = 0Eh
DL = Номер дисковода (0 — А:, 1 — В:, и т.д.)
На выходе: AL = Общее количество дисководов в системе. Эта величина соответствует параметру LASTDRIVE файла CONFIG.SYS.

Для того чтобы узнать номер текущего дисковода, программа может воспользоваться функцией 19h :

На входе: AH = 19h
На выходе: AL = Номер текущего дисковода (0 — А:, 1 — В:, и т.д.).

Функция 3Bh предназначена для установки текущего каталога:

На входе: AH = 3Bh
DL = Номер дисковода (0 — текущий, 1 — А:, 2 — В:, и т.д.)
DS:DX = Адрес буфера, содержащего путь каталога, который должен стать текущим.
На выходе: AX = Код ошибки, если CY установлен в 1 .

Буфер пути может иметь максимальный размер 64 байта. Он должен содержать путь в формате ASCIIZ, т.е. строку, закрытую двоичным нулем, например: «pathdirname»,0 . Строка не должна содержать литеры, обозначающие диск. Если текущим должен стать корневой каталог, строка должна состоять только из одного двоичного нуля.

Для того чтобы узнать текущий каталог, вы можете воспользоваться функцией 47h :

На входе: AH = 47h
DL = Номер дисковода ( 0 — текущий, 1 — А:, 2 — В: , и т.д.)
DS:SI = Адрес буфера для записи пути текущего каталога.
На выходе: AX = Код ошибки, если флаг переноса CF установлен в 1 .

Буфер должен иметь размер не менее 64 байтов, текущий каталог возвращается в формате ASCIIZ без литеры, обозначающей диск. Если текущим является корневой каталог, регистровая пара DS:SI будет указывать на нулевую строку (состоящую из одного двоичного нуля).

Функции MS-DOS могут помочь вам в получении информации, необходимой для организации доступа к диску на уровне секторов и кластеров. При этом вы будете избавлены от необходимости читать в память и анализированть содержимое загрузочного сектора логического диска.

Информация о таблице размещения файлов FAT для текущего диска может быть получена с помощью функции 1Bh прерывания INT 21h , имеющего следующий формат:

На входе: AH = 1Bh
На выходе: DS:BX = Адрес первого байта FAT . Это байт ID идентификации среды носителя данных, соответствует байту media в блоке параметров BIOS.
DX = Общее количество кластеров на диске.
AL = Количество секторов в одном кластере.
CX = Количество байтов в одном секторе.

Дополнительно эта функция возвращает информацию об общем количестве кластеров на диске, размере кластера в секторах и размере сектора в байтах. Для версий MS-DOS, более ранних, чем 2.0, регистровая пара DS:BX указывала на FAT , считанный в память. Более поздние версии операционной системы могут содержать по этому адресу только часть таблицы размещения файлов.

Для получения аналогичной информации не о текущем, а о любом диске, используйте функцию 1Ch . Эта функция полностью аналогична предыдущей, за исключением того, что в регистре DL должен быть указан код дисковода: 0 — текущий, 1 — А:, 2 — В: и т.д. Эта функция доступна в MS-DOS версии 2.0 и в более поздних версиях.

Если вас интересует размер свободного места на диске, вы можете его узнать с помощью функции 36h , имеющей следующий формат:

На входе: AH = 36h
DL = Номер дисковода ( 0 — текущий, 1 — А:, 2 — В: , и т.д.)
На выходе: AX = Количество секторов в кластере; 0FFFFh , если был задан неправильный номер дисковода;
BX = Количество свободных кластеров на диске.
CX = Количество байтов в одном секторе.
DX = Общее количество кластеров на диске.

Эта функция возвращает в регистре AX число 0FFFFh , если вы неправильно указали номер дисковода.

При обсуждении векторной таблицы связи мы рассказывали о блоках управления устройствами DDCB . Поле dev_cb векторной таблицы связи содержит FAR -адрес цепочки этих блоков.

Приведем еще раз формат блока DDCB . Напомним, что он изменяется в зависимости от версии DOS. Для версий 2.х и 3.х блок DDCB имеет следующий формат:

(0) 1 drv_num номер устройства ( 0 соответствует устройству А: , 1 — В: и т.д.)
(+1) 1 drv_numd дополнительный номер устройства внутри драйвера
(+2) 2 sec_size размер сектора в байтах
(+4) 1 clu_size число, на единицу меньшее количества секторов в кластере
(+5) 1 clu_base если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size
(+6) 2 boot_siz количество зарезервированных секторов (boot-сектора, начало корневого каталога)
(+8) 1 fat_num количество копий FAT
(+9) 2 max_dir максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве)
(+11) 2 data_sec номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2)
(+13) 2 hi_clust максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных)
(+15) 1 fat_size количество секторов, занимаемых одной копией FAT
(+16) 2 root_sec номер первого сектора корневого каталога
(+18) 4 drv_addr FAR -адрес заголовка драйвера, обслуживающего данное устройство
(+22) 1 media байт описания среды носителя данных
(+23) 1 acc_flag флаг доступа, 0 означает, что к устройству был доступ
(+24) 4 next адрес следующего блока DDCB , для последнего блока в поле смещения находится число FFFF
————— только для DOS 2.x —————
(+28) 2 dir_clu номер начального кластера текущего каталога (0 для корневого каталога)
(+30) 64 dir_path строка в формате ASCIIZ, содержащая путь к текущему каталогу
————— DOS 3.х —————————-
(+28) 2 reserv1 зарезервировано, обычно равно 0
(+30) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Формат блока DDCB для DOS версии 4.х:


(0) 1 drv_num номер устройства ( 0 соответствует устройству А:, 1 — В: и т.д.)
(+1) 1 drv_numd дополнительный номер устройства внутри драйвера
(+2) 2 sec_size размер сектора в байтах
(+4) 1 clu_size число, на единицу меньшее количества секторов в кластере
(+5) 1 clu_base если содержимое этого поля не равно нулю, то для получения общего числа секторов в кластере надо возвести 2 в степень clu_base и получившееся число прибавить к clu_size
(+6) 2 boot_siz количество зарезервированных секторов (boot-сектора, начало корневого каталога)
(+8) 1 fat_num количество копий FAT
(+9) 2 max_dir максимальное число дескрипторов файлов в корневом каталоге (т.е. максимальное число файлов, которое может содержать корневой каталог на этом устройстве)
(+11) 2 data_sec номер первого сектора данных на диске (номер сектора, соответствующего кластеру номер 2)
(+13) 2 hi_clust максимальное количество кластеров (равно увеличенному на 1 количеству кластеров данных)
(+15) 1 fat_size количество секторов, занимаемых одной копией FAT
(+16) 1 reserv1 зарезервироано
(+17) 2 root_sec номер первого сектора корневого каталога
(+19) 4 drv_addr FAR -адрес заголовка драйвера, обслуживающего данное устройство
(+23) 1 media байт описания среды носителя данных
(+24) 1 acc_flag флаг доступа, 0 означает, что к устройству был доступ
(+25) 4 next адрес следующего блока DDCB , для последнего блока в поле смещения находится число FFFF
(+29) 2 reserv2 зарезервироано
(+31) 2 built число FFFF в этом поле означает, что блок DDCB был построен

Файл sysp.h содержит определение типа DDCB для MS-DOS версии 4.х:

При описании векторной таблицы связи мы приводили примеры использования блоков DDCB . Для получения адреса блока DDCB конкретного дисковода можно воспользоваться недокументированной функцией 32h . Она имеет следующий формат вызова:

На входе: AH = 32h
DL = Номер дисковода ( 0 — текущий, 1 — А:, 2 — В: , и т.д.)
На выходе: AL = 0, если был задан правильный номер дисковода;
0FFh , если был задан неправильный номер дисковода;
DS:BX = Адрес блока DDCB

Для получения адреса блока DDCB текущего диска можно воспользоваться недокументированной функцией 1Fh , которая имеет формат, аналогичный функции 32h , за исключением того, что не надо задавать номер дисковода в регистре DL .

Какая еще полезная информация может быть получена при использовании функций MS-DOS?

С помощью функции 33h программа может проверить или установить флаг Ctrl-Break и узнать номер диска, с которого выполнялась загрузка операционной системы:

На входе: AH = 33h
AL = Код подфункции:
0 — Проверить текущее состояние флага Ctrl-Break;
1 — Установить флаг Ctrl-Break;
5 — Определить номер диска, который был использован для загрузки операционной системы.
DL = Значение устанавливаемого флага Ctrl-Break для подфункции 1 (0 — OFF, 1 — ON).
На выходе: DL = Текущее состояние флага Ctrl-Break для подфункции 0;
Номер диска, использованного для загрузки операционной системы для подфункции 5 ( 1 — А:, 2 — В: , и т.д.).

Сведения о диске, который был использован для загрузки операционной системы, могут понадобиться вам для поиска файла, содержащего командный интерпретатор или программу DOSSHELL .

Состояние флага Ctrl-Break влияет на возможность прервать выполнение программы нажатием комбинации клавиш Ctrl-Break или Ctrl-C. Если флаг находится в состоянии OFF, DOS проверяет эту комбинацию клавиш только при вызове функций стандартного ввода/вывода на консоль, принтер и последовательный порт. Если флаг установлен в состояние ON, комбинация клавиш проверяется и при вызове других функций MS-DOS. Если операционная система зафиксировала нажатие указанной комбинации клавиш, она выполняет прерывание INT 23h , которое завершает работу текущей программы.

Функция 2Fh возвращает в регистровой паре ES:BX адрес текущей области DTA (Disk Transfer Area), которая используется при поиске файлов в каталогах.

Функция 54h позволяет программе узнать текущее состояние флага проверки записывающейся на диск информации. В регистре AL эта функция возвращает текущее состояние флага. Если содержимое регистра равно 1, операционная система после записи сектора считывает его для проверки. Разумеется, такая проверка снижает скорость работы программы. Если после вызова функции регистр AL содержит 0, проверка записи не выполняется.

Для установки флага проверки записи можно использовать функцию 2Eh . Перед вызовом функции в регистр AL необходимо занести новое значение флага проверки: 0 — проверка не нужна; 1 — должна выполняться проверка записанной информации.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат несколько функций, облегчающих получение справочной информации о состоянии дисковой подсистемы.

Функция _dos_getdiskfree() использует функцию 36h для получения информации о диске. Файл dos.h содержит описание этой функции:

Параметр drive задает номер используемого дисковода: 0 — текущий, 1 — А: , и т.д.

Информация возвращается в структуре diskfree_t , которая определена в файле dos.h:

В этой структуре:

unsigned total_clusters общее количество кластеров на диске;
unsigned avail_clusters количество свободных кластеров;
unsigned sectors_per_cluster количество секторов, занимаемых кластером;
unsigned bytes_per_sector размер сектора в байтах.

Для получения номера текущего диска и для установки номера текущего диска можно использовать, соответственно, функции _dos_getdrive() и _dos_setdrive().

Функция _dos_getdrive() имеет формат:

Эта функция пользуется функцией 19h для получения номера текущего диска, который записывается по адресу, задаваемому параметром. Значение 1 соответствует диску А:, 2 — В:, и т.д.

Функция _dos_setdrive() предназначена для установки текущего диска и может быть использована для определения общего числа дисков в системе:

Параметр drive опеределяет текущий диск ( 1 — А: , и_т.д.), по адресу, задаваемому вторым параметром, функция записывает общее количество логических дисков, установленных в системе. Функция _dos_setdrive() использует функцию 0Eh прерывания INT 21h.

Для иллюстрации способов использования функций _dos_getdrive(), _dos_setdrive(), _dos_getdiskfree() мы составили следующую программу:

После форматирования логический диск содержит корневой каталог. Если диск форматируется как системный, в этом каталоге могут находится дескрипторы файлов операционной системы IO.SYS, MSDOS.SYS, COMMAND.COM.

Операционная система предоставляет программам пользователя удобный сервис для создания, уничтожения и переименования каталогов. Используя сведения, приведенные в этой книге, вы сможете изменять структуру каталогов сами, не прибегая к услугам MS-DOS. Однако это следует делать только тогда, когда операции с каталогами по каким-то причинам нежелательно выполнять с использованием функций операционной системы.

Для создания каталога используйте функцию 39h прерывания INT 21h:

На входе: AH = 39h
DS:DX = Адрес строки в формате ASCIIZ, содержащей имя создаваемого каталога.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

Строка, имени создаваемого каталога может содержать полный путь, состоящий из имени диска и имени каталога, в котором должен быть создан каталог, или она может состоять только из одного имени каталога. В последнем случае каталог создается в текущем каталоге на текущем диске.

Размер строки с именем каталога не должен превышать по длине 64 байта.

Удалить существующий каталог можно с помощью функции 3Ah . Формат вызова этой функции аналогичен предыдущему:

На входе: AH = 3Ah
DS:DX =Адрес строки в формате ASCIIZ, содержащей имя удаляемого каталога.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

Необходимо заметить, что удалить можно только пустой каталог. И это понятно, так как если вы в обход операционной системы удалите непустой каталог, то описанные в этом каталоге файлы и каталоги будут потеряны для вас, а занимаемое ими место невозможно будет распределить другим файлам.

Для изменения имени каталогов и файлов предназначена функция 56h :

На входе: AH = 56h
DS:DX = Адрес строки в формате ASCIIZ, содержащей старое имя каталога или файла.
ES:DI = Адрес строки в формате ASCIIZ, содержащей новое имя каталога или файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

Переименуемый файл или каталог должен существовать. Если в имени не указан диск или каталог, то подразумевается, что файл или каталог находится в текущем каталоге на текущем диске. Напротив, каталога или файла с новым именем не должно быть, иначе функция возвратит признак ошибки.

Эта функция может перемещать файл из одного каталога в другой, если вы укажите разные пути. Каталоги перемещать нельзя, их можно только переименовывать.

Мы уже рассказывали о функции 3Bh , с помощью которой можно изменить текущий каталог, если это необходимо.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат несколько функций, предназначенных для работы с каталогами.

Функция getcwd() предназначена для определения текущего каталога. Прототип этой функции описан в файле direct.h:

Первый параметр этой функции — адрес буфера, в который необходимо занести строку, содержащую имя текущего каталога. Размер этого буфера определяется вторым параметром.

Если в качестве первого параметра указать NULL , функция динамически закажет буфер длиной n байтов из области кучи. Эту память впоследствии необходимо будет освободить при помощи функции free() . Функция getcwd() возвращает указатель на буфер, содержащий текущий каталог.

Приведем пример простой программы, которая выводит на экран информацию о текущем каталоге:

Для создания и удаления каталогов, изменения текущего каталога имеются функции mkdir(), rmdir(), chdir().

Все эти функции имеют один параметр — путь каталога, который имеет тип (char_*). В случае успешного выполнения операции функции возвращают 0 , при ошибке — 1 .

Приведем небольшой пример, использующий перечисленные выше функциии:

Для переименования каталогов (и файлов) предназначена функция rename():

Способ ее использования очевиден: необходимо задать старое и новое имена каталогов. Можно задавать как полный путь, так и просто имя каталога/файла. В последнем случае операция переименования выполняется над каталогами или файлами, находящимися в текущем каталоге.

Функция может возвращать один из кодов ошибки:

ENOENT Нет такого файла или каталога
EACCES Нет прав доступа
EXDEV Другой диск

Код ошибки EXDEV возвращается в том случае, когда программа указывает разные диски для старого и нового имен файлов или каталогов.

Важное замечание: если вы задаете полный путь, в строке пути повторяйте символ » два раза. Это нужно для того, чтобы избежать конфликта с форматом представления констант в языке С. Например:

Часто перед программистом стоит задача определения текущего содержимого каталога. При описании логической структуры диска мы приводили текст программы, выводящей на экран содержимого корневого каталога и других каталогов. Эта программа использовала загрузочный сектор логического диска и таблицу размещения файлов. Вы можете использовать такой способ, однако, если вам не требуется информация о номерах начальных кластеров файлов и дескрипторы удаленных файлов, лучше применить специальные функции MS-DOS, предназначенные для поиска файлов в каталогах.

Пара функций 4Eh и 4Fh предназначены для сканирования каталогов.

Эти функции используются вместе следующим образом:

  • Вызывается функция 4Eh для поиска в каталоге файла, соответствующего образцу. В образце можно использовать символы ? и *, которые означают, соответственно, один любой символ и любое количество любых символов. Информация о найденном файле располагается в специальной области, назначенной каждой работающей программе — области DTA .
  • Вызывается в цикле функция 4Fh для поиска остальных файлов, удовлетворяющих образцу, заданному при вызове функции 4Eh . Условие завершения цикла — отсутствие в каталоге указанных файлов.

Приведем формат вызова функций 4Eh и 4Fh .

На входе: AH = 4Eh
CX = Атрибуты файла, которые будут использованы при поиске. Будут найдены файлы, имеющие заданный в этом регистре атрибут.
DS:DX = Адрес строки в формате ASCIIZ, содержащей путь каталогаили файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

На входе: AH = 4Fh
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

Обе функции устанавливают флаг переноса в том случае, когда каталог не содержит файлов, удовлетворяющих заданному критерию поиска.

Для работы с областью DTA MS-DOS имеет две функции. Это функция 2Fh , позволяющая получить адрес области DTA (она возвращает этот адрес в регистрах ES:BX ), и функция 1Ah , предназначенная для установки своей области DTA (адрес новой области DTA должен быть указан в регистрах DS:DX ).

Напомним, что по умолчанию область DTA занимает 128 байтов в префиксе сегмента программы PSP со смещением 80h .

В случае успешного поиска функции 4Eh и 4Fh помещают в DTA информацию о найденных файлах в следующем формате:

(0) 20 Зарезервировано.
(+21) 1 Атрибуты найденного файла
(+22) 2 Поле времени последнего обновления фалйла
(+24) 2 Поле даты последнего обновления фалйла
(+26) 4 Длина файла
(+30) 13 Имя файла и расширение в формате ASCIIZ

Номер начального класетра, распределенного файлу или каталогу, невозможно получить с помощью функций 4Eh и 4Fh .

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат две функции, предназначенные для сканирования каталогов — _dos_findfirst() и _dos_findnext() .

Приведем прототипы этих функций, описанные в файле dos.h :

В этих функциях параметр pattern определяет образец для поиска файлов, параметр attr — атрибуты файла — используется в качестве дополнительного критерия поиска. Параметр found представляет собой указатель на структуру, в которую будет записываться информация о найденных файлах. Эта структура определена в файле dos.h :

Приведем текст программы просмотра содержимого каталога. Программа принимает из командной строки параметр — образец для показа файлов. Если вы укажете параметр *.* , будет выведена информация обо всех файлах. Можно задавать полный путь: c:*.* .

При запуске программы с параметром *.com на экран будет выведена информация:

В этом разделе мы рассмотрим функции MS-DOS, предназначенные для создания, переименования, удаления и перемещения файлов. Операции чтения из файла и записи в файл будут описаны в следующем разделе.

Для создания файла предназначена функция 3Ch прерывания INT 21h . С помощью этой функции может быть создан файл как в текущем, так и в любом другом каталоге. Если файл с указанным именем уже существует, он обрезается до нулевой длины. Будьте осторожны при использовании этой функции — она может уничтожить нужный вам файл.

Дополнительно функция 3Ch выполняет операцию открытия только что созданного файла, возвращая программе файловый индекс. При создании файла программа может указать требуемые атрибуты, которые будут использованы другими функциями для определения возможности предоставления доступа к файлу.

Приведем формат вызова функции создания файла:

На входе: AH = 3Ch
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес строки, содержащей путь создаваемого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0.

При выполнении этой функции возможны следующие ошибки:

  • отсутствует какой-либо элемент в пути для создаваемого файла, например, диск или каталог;
  • была сделана попытка создать файл в корневом каталоге, но корневой каталог переполнен;
  • в указаннном каталоге уже есть файл с таким именем, и этот файл имеет атрибут «Только читаемый»;
  • пользователь, который работает в сети, не имеет прав доступа для выполнения указанной операции.

Операционная система игнорирует попытки создания с помощью этой функции каталогов или метки диска.

Для того, чтобы случайно не уничтожить содержимое файла с таким же именем, как и создаваемый, программа может использовать функцию 5Bh . Эта функция проверяет заданный путь на предмет наличия указанного файла. Если такой файл уже существует, функция возвращает программе признак ошибки.

Формат вызова функции:

На входе: AH = 5Bh
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес строки, содержащей путь создаваемого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0 .

Если вам требуется временный файл, вы можете создать его с помощью функции 5Ah :

На входе: AH = 5Ah
CX = Атрибуты создаваемого файла:
00h — обычный файл;
01h — только читаемый файл;
02h — скрытый файл;
04h — системный файл.
DS:DX = Адрес буфера, в который функция запишет путь созданного временного файла. Размер этого буфера должен быть по крайней мере 13 байтов.
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Файловый индекс, если флаг переноса сброшен в 0 .

Операционная система не будет автоматически удалять созданный временный файл после завершения работы программы или перезагрузки. Программа должна сама удалить этот файл.

Перед тем, как начать работу с файлом, его нужно открыть. Функции, создающие новые файлы, открывают новые файлы автоматически. Для того, чтобы открыть существующий файл, вы можете воспользоваться функцией 3Dh :

На входе: AH = 3Dh
AL = Требуемый режим доступа:

Бит 7: флаг наследования

0 — файловый индекс наследуется порожденным процессом
1 — файловый индекс не наследуется порожденным процессом

Биты 4. 6: режим разделения

000 — режим совместимости
001 — запрещение всех видов доступа
010 — запрещение записи
011 — запрещение чтения
100 — разрешение всех видов доступа

Бит 3:0 — зарезервировано

Биты 0. 2: вид доступа

000 — чтение
001 — запись
010 — чтение/запись

DS:DX = Адрес строки, содержащей путь открываемого файла
На выходе: AX = Код ошибки, если флаг переноса CF был установлен в 1 ;
Файловый индекс, если флаг переноса сброшен в 0 .

С помощью функции 3Dh можно открыть любой файл (но не каталог). Если требуется вид доступа «запись», открываемый файл не должен иметь атрибут «Только читаемый».

Для использования битов 4. 7 (управляющих доступом к файлу другими программами в сети) должна быть запущена программа SHARE.EXE.

Если используется бит наследования, то порожденному процессу наследуются запрошенный при открытии файла вид доступа.

Операционная система MS-DOS версии 4.0 имеет в своем составе функцию 6Ch , обладающую расширенными возможностями по созданию и открытию файлов:

На входе: AH = 6Ch
AL = 00h
BX = байт флагов расширенного режима открытия файла
CX = атрибуты создаваемого файла, используется только при создании файлов
DX = выполняемая функция, если файл существует или не существует:

Биты 0-3 регистра DX задают действие, если файл существует:

0000h — если файл существует, вернуть признак ошибки
0001h — если файл существует, открыть его
0002h — если файл существует, заместить и открыть его

Биты 4-7 регистра DX задают действие, если файл не существует:

0000h — если файл не существует, вернуть признак ошибки
0001h — если файл не существует, создать и открыть его

DS:SI = Адрес строки, содержащей путь открываемого файла
На выходе: AX = Код ошибки, если флаг переноса CF был установлен в 1 ;
Файловый индекс, если флаг переноса сброшен в 0 .
CX = Код выполненных действий:
0 — файл был открыт
1 — файл был создан и открыт
2 — файл был замещен и открыт

Регистр BX на входе задает флаги расширенного режима открытия файла в следующем формате:

Биты Назначение
0. 2 Режим доступа при чтении/записи
3 Зарезервировано, должно быть равно 0
4. 6 Режим разделения
7 Флаг наследования
8. 12 Зарезервировано, должно быть равно 0
13 0 — Режим обычного использования обработчика критических ошибок INT 24h
1 — Блокировка обработчика критических ошибок INT 24h. Для того, чтобы узнать причину ошибки, программа должна использовать функцию 59h прерывания INT 21h MS-DOS.
14 Управление буферизацией:
0 — Использование стандартной для MS-DOS буферизации.
1 — Отмена буферизации. Использование этого режима замедлит работу с диском, однако вероятность потери информации при аварии в питающей сети уменьшится.

Описанная выше функция является как бы комбинацией функций 3Dh и 3Ch (открытие и создание файла). Она удобна, но при ее использовании программа должна убедиться в том, что версия используемой операционной системы не ниже, чем 4.0.

Удалить файл можно при помощи функции 41h прерывания INT 21h:

На входе: AH = 41h
DS:DX = Адрес строки в формате ASCIIZ, содержащей имя удаляемого файла.
На выходе: AL = Код ошибки, если был установлен в 1 флаг переноса CF .

С помощью этой функции нельзя удалить файл, имеющий атрибут «Только читаемый».

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

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции для работы с файлами. Эти функции можно разделить на две группы — функции ввода/вывода низкого уровня и функции ввода/вывода потоком. Вторая группа функций использует буферизацию и будет рассмотрена в разделе, посвященном буферизованному вводу/выводу.

Функции ввода/вывода низкого уровня отображаются на описанные выше функции прерывания INT 21h (и функции этого же прерывания, предназначенные для чтения/записи, позиционирования и т.д.).

Для создания файла можно использовать функцию creat() :

Эта функция и ее параметры описаны в файлах io.h, systypes.h, sysstat.h, errno.h.

Первый параметр определяет путь создаваемого файла и его имя. Если файл с указанным именем существует, и не имеет атрибута «Только читаемый», функция сбрасывает длину файла до нуля. Предыдущее содержимое файла при этом уничтожается.

Второй параметр позволяет задать атрибуты создаваемого файла. Он может иметь следующие значения:

S_IWRITE для создаваемого файла разрешена операция записи;
S_IREAD для создаваемого файла разрешена операция чтения;
S_IREAD | S_IWRITE для создаваемого файла разрешены операции чтения и записи.

В операционных системах MS-DOS и OS/2 невозможно создать файл, в который можно было бы писать, но из которого было бы нельзя читать информацию. Поэтому задание второго параметра как S_IWRITE приведет к созданию такого файла, для которого разрешены как операция записи, так и операция чтения.

После создания файла функция creat() открывает новый файл и возвращает файловый индекс ( handle ) или код ошибки.


Мощная функция open() предназначена как для открытия существующих файлов, так и для создания новых:

Первый и третий параметры в этой функции аналогичны параметрам функции creat(), причем третий параметр нужен только при создании нового файла. Квадратные скобки указывают на то, что этот параметр является необязательным.

Параметр oflag может являться результатом битовой операции ИЛИ над следующими константами, определенными в файле fcntl.h:

O_APPEN при записи в файл информация будет добавляться в конец файла;
O_BINARY файл открывается для работы в двоичном режиме (игнорируются управляющие символы, такие как конец строки);
O_CREAT создается новый файл и открывается для записи; эта константа игнорируется, если указанный в первом параметре файл уже существует;
O_EXCL используется вместе с O_CREAT ; если указанный в первом параметре файл существует, функция возвратит признак ошибки;
O_RDONLY файл открывается только для чтения, попытка записи в файл приведет к тому, что функция записи вернет признак ошибки;
O_RDWR файл открывается как для чтения, так и для записи;
O_TEXT файл открывается в текстовом режиме;
O_TRUNC существующий файл открывается и обрезается до нулевой длины (если для этого файла разрешена операция записи);
O_WRONLY файл открывается только для записи (в операционных системах MS-DOS и OS/2 для файла, открытого с признаком O_WRONLY разрешено выполнение операции чтения).

Для того, чтобы закрыть файл, открытый функциями creat() или open() , нужно использовать функцию close():

В качестве параметра функции передается файловый индекс, полученный при открытии или создании файла. Функция возвращает 0 при успешном закрытии файла, или -1 при ошибке.

Код ошибки для этой и других функций cтандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0 записывается в глобальную переменную errno.

После того, как вы открыли файл, можно выполнять над ним операции чтения/записи. Для записи данных в файл предназначена функция 40h прерывания INT 21h . В качестве параметров для этой функции необходимо задать файловый индекс, полученный при открытии существующего файла или создании нового, адрес буфера, содержащего записываемые данные и количество записываемых байтов:

На входе: AH = 40h
BX = файловый индекс открытого файла
CX = количество записываемых байтов
DS:DX = Адрес буфера, содержащего записываемые данные
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Количество действительно записанных байтов, если флаг переноса CF сброшен в 0 .

При записи данные попадают в то место внутри файла, которое определяется содержимым так называемого файлового указателя позиции. При создании нового файла этот указатель сбрасывается в 0, что соответствует началу файла. При открытии файла с помощью функции 3Dh указатель также устанавливается на начало файла. Операция записи в файл с помощью функции 40h продвигает указатель вперед к концу файла на количество записываемых байтов.

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

Если вам необходимо перезаписать содержимое файла, а не дописывать данные в конец, необходимо воспользоваться функцией позиционирования. Эта функция позволяет управлять содержимым файлового указателя позиции, она будет описана в следующем разделе.

Следует учитывать, что количество действительно записанных байтов может не совпадать с заданным в регистре CX при вызове функции 40h . Такая ситуация возможна, например, при записи в файл, открытый в текстовом режиме, байта Ctrl-Z (1Ah) . Этот байт означает конец текстового файла. Другая возможная причина — отсутствие свободного места на диске.

Если функция вызывается с содержимым регистра CX , равным 0 , файл будет обрезан или расширен до текущего положения файлового указателя.

Разумеется, что если программа, выполняющая запись в файл, работает в сети, она должна иметь соответствующие права доступа к каталогу и файлу.

Функция 40h может выполнять запись не только в файл, но и в устройство посимвольной обработки, предварительно открытое функцией 3Dh . Об этом мы говорили в разделах книги, посвященных драйверам.

Для чтения данных из файла (или устройства посимвольной обработки) предназначена функция 3Fh прерывания INT 21h :

На входе: AH = 3Fh
BX = файловый индекс открытого файла
CX = количество читаемых байтов
DS:DX = Адрес буфера для данных
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Количество действительно прочитанных байтов, если флаг переноса CF сброшен в 0 .

Эта функция используется аналогично функции записи. Для нее верны все замечания, касающиеся файлового указателя позиции, количества действительно прочитанных байтов и прав доступа.

Если ваша программа составлена на языке программирования С, для записи и чтения данных она может воспользоваться функциями write() и read() :

Эти функции работают аналогично функциям 40h и 3Fh прерывания INT 21h . Параметр handle определяет файл, для которого необходимо выполнить операцию записи или чтения. Параметр buffer — указатель на буфер, который содержит данные для записи или в который необходимо поместить прочитанные данные. Количество записываемых/читаемых байтов определяется третьим параметром — count .

После выполнения операции функция возвращает количество действительно записанных или прочитанных данных или -1 при ошибке. Будьте внимательны, если вы записываете или читаете больше 32К байтов — вы можете получить признак ошибки, хотя передача данных выполнилась правильно. Большие массивы данных можно записывать по частям.

В качестве примера мы приведем программу копирования файлов, которая пользуется описанными выше функциями ввода/вывода:

В приведенной программе для определения конца исходного файла использована функция eof():

Для файла с файловым индексом handle эта функция возвращает одно из трех значений:

1 достигнут конец файла;
конец файла не достигнут;
-1 ошибка, например, неправильно указан handle .

Программа, которая читает файл с помощью функции 3Fh прерывания INT 21h , может определить момент достижения конца файла, анализируя код ошибки в регистре AX .

Управляя содержимым файлового указателя позиции, программа может произвольно считывать или перезаписывать различные участки файла, то есть организовать прямой доступ к содержимому файла. Прямой доступ к файлу может вам понадобится, например, для создания систем управления базами данных.

Установить файловый указатель в нужную вам позицию можно с помощью функции 42h прерывания INT 21h MS-DOS:

На входе: AH = 42h
AL = метод кодирования:
00h абсолютное смещение от начала файла
01h смещение от текущей позиции
02h смещение от конца файла
BX = файловый индекс открытого файла
CX = старший байт смещения
DX = младший байт смещения
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
Младший байт текущей позиции, если флаг переноса CF сброшен в 0.
DX = Старший байт текущей позиции

Функция позволяет указывать новое значение указателя либо как абсолютное смещение от начала файла, либо как смещение от текущей позиции, либо как смещение от конца файла. В последних двух случаях используется смещение со знаком. Для указания смещения или абсолютной позиции программа должна задать в регистрах CX, DX 32-битовое значение.

Если использовать метод кодирования 02h и задать нулевое смещение, функция установит указатель на конец файла. Это обстоятельство может быть использовано для определения размера файла в байтах.

Что произойдет, если при использовании методов кодирования 01h или 02h попытаться установить указатель позиции до начала файла?

Функция 42h при этом не возвратит признак ошибки, однако если будет сделана попытка прочитать или записать данные, то соответствующая функция чтения/записи завершится с ошибкой.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции, предназначенные для управления содержимым файлового указателя позиции и получения текущего значения этого указателя. Это функции lseek(), tell(), filelength() .

Функция lseek() работает аналогично только что описанной функции 42h . Приведем ее прототип:

Первый параметр определяет файл, для которого выполняется операция позиционирования. Параметр offset определяет смещение. Последний параметр задает метод кодирования смещения. Он может принимать следующие значения, описанные в фале stdio.h :

SEEK_SET Абсолютное смещение от начала файла
SEEK_CUR Смещение относительно текущей позиции
SEEK_END Смещение относительно конца файла

Функция возвращает величину текущего смещения в байтах относительно начала файла или -1L , в случае ошибки. Как и для остальных функций библиотеки С, код ошибки находится в глобальной переменной errno .

Вы, конечно, можете использовать функцию lseek() для определения размера файла или текущей файловой позиции. Однако для того, чтобы узнать размер файла, лучше воспользоваться специальной функцией filelength() :

Функция возвращает размер файла в байтах. Файл задается параметром handle . В случае ошибки функция возвращает значение -1L.

Для того, чтобы определить текущую файловую позицию, можно использовать функцию tell() :

Эта функция возвращает текущую позицию для файла, определенного параметром handle , или -1L , в случае ошибки.

Для демонстрации использования функций позиционирования приведем простую программу, которая для заданного файла и позиции внутри файла отображает содержимое одного байта. Дополнительно программа определяет размер файла и текущую позицию после чтения байта.

Напомним: атрибуты файла, время и дата его последней модификации, а также размер файла хранятся в дескрипторе файла. Дескриптор файла находится в каталоге.

Операционная система предоставляет вам все необходимые средства для изменения всех полей дескриптора файла, кроме номера начального кластера. Для изменения этого номера вам придется работать с каталогом через таблицу размещения файлов FAT . Вам придется сначала считать каталог по кластерам с помощью прерывания INT 25h, модифицировать нужные поля и записать каталог обратно на диск при помощи прерывания INT 26h.

Для работы с полем атрибутов файла предназначена функция 43h прерывания INT 21h:

На входе: AH = 43h
AL = выполняемая операция:
00h чтение атрибутов файла
01h установка новых атрибутов файла
CX = новые атрибуты файла, если AL = 01h:
Биты:
5 — бит архивации
4 — каталог
3 — метка диска
2 — системный файл
1 — скрытый файл
0 — только читаемый файл
DS:DX = путь файла в формате ASCIIZ
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF
CX = Если не было ошибки, этот регистр содержит атрибуты файла

При изменении атрибутов файла допустимо указывать комбинации битов в регистре CX .

Если ваша программа работает в сети, она должна иметь соответствующие права доступа к каталогу, содержащему файл, для которого программа собирается изменять байт атрибутов.

Для работы с полями времени и даты последней модификации файла предназначена функция 57h прерывания INT 21h:

На входе: AH = 57h
AL = выполняемая операция:
00h чтение даты и времени
01h установка даты и времени
BX = файловый индекс открытого файла
CX = время
DX = дата
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF
CX = Если не было ошибки, этот регистр содержит время последнего изменения файла
DX = Если не было ошибки, этот регистр содержит дату последнего изменения файла

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

Формат поля времени:

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции для чтения и изменения атрибутов файлов и времени/даты их последней модификации.

Для определения атрибутов файла можно использовать функцию _dos_getfileattr() :

Эта функция получает атрибуты файла, заданного первым аргументом, и записывает байт атрибутов в младший байт по адресу, указанному вторым параметром.

В случае успешного завершения функция возвращает 0 , в противном случае она возвращает код ошибки, полученный от операционной системы и устанавливает глобальную переменную errno в значение ENOENT , что означает отсутствие указанного в параметре path файла.

Для изменения атрибутов файла можно использовать функцию _dos_setfileattr():

Параметр attrib может принимать следующие значения:

_A_ARCH установка бита архивации
_A_HIDDEN файл скрытый
_A_NORMAL обычный файл
_A_RDONLY только читаемый файл
_A_SUBDIR каталог
_A_SYSTEM системный файл
_A_VOLID метка диска

Для определения времени последней модификации файла можно использовать функцию _dos_getftime():

Перед использованием этой функции программа должна открыть файл. Дата и время записываются по адресу, указываемому, соответственно, вторым и третьим параметрами.

Если вам надо изменить время или дату последней модификации файла, используйте функцию _dos_setftime():

Параметры этой функции аналогичны используемым в функции _dos_getftime() , за исключением того, что в качестве второго и третьего параметра применяются не указатели, а непосредственные значения даты и времени.

Приведем программу, изменяющую при запуске значение бита файла атрибутов «Только читаемый» для файла, имя которого передается программе в качестве параметра:

Программа сначала считывает байт атрибутов, затем инвертирует соответствующий бит и устанавливает новое значение байта атрибутов.

Ввод/вывод для дисков в операционной системе MS-DOS буферизован. Это означает, что данные не сразу записываются на диск, а накапливаются в специальном массиве (буфере). По мере заполнения буфер сбрасывается на диск. При чтении информация заполняет весь входной буфер, независимо от количества байтов, которые программа читает из файла. В дальнейшем, если программе потребуются данные, которые уже были считаны с диска и записаны во входной буфер, она получит данные непосредственно из этого буфера. Обращения к диску при этом не будет.

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

Операционная система MS-DOS имеет несколько буферов. Их количество зависит от оператора BUFFERS , находящегося в файле CONFIG.SYS . Этот оператор позволяет определить от 2 до 99 буферов. Если файл CONFIG.SYS не содержит оператора BUFFERS , по умолчанию используются два буфера.

При увеличении количества буферов увеличивается вероятность того, что нужная часть файла уже считана и находится в оперативной памяти. Однако необходимо учитывать, что для хранения буферов расходуется основная оперативная память. Кроме того, с ростом количества буферов увеличивается время, необходимое операционной системе на анализ состояния буферов, что может привести к снижению производительности. Значительное снижение скорости работы наступает при количестве буферов порядка 50.

Обычно для машин класса AT с диском размером 20-40 мегабайтов рекомендуется использовать 32 буфера, однако для каждого конкретного случая может потребоваться подбор этого параметра для оптимизации производительности системы.

Если ваша программа интенсивно использует обращение к каталогам файловой системы, вы можете использовать утилиту MS-DOS FASTOPEN , которая запоминает в оперативной памяти расположение на диске файлов и каталогов, уменьшая интенсивность обращения к диску. Например, при использовании следующей команды в оперативной памяти будет храниться информация о расположении максимально о 100 файлах и каталогах:

В операционной системе MS-DOS версии 4.0 вы можете указать для утилиты FASTOPEN опцию /X . Эта опция вызывает размещение информации о файлах и каталогах в дополнительной ( expanded ) памяти. Для этой версии операционной системы вызов утилиты FASTOPEN лучше всего выполнять через оператор INSTALL файла CONFIG.SYS:

В приведенной выше строке используются следующие обозначения:

d: обозначение диска;
n количество файлов или каталогов, для которых необходимо запомнить расположение, может иметь значение от 1 до 999, по умолчанию используется 34;
m количество буферов для фрагментированных файлов, может иметь значение от 1 до 999, по умолчанию используется 34;
/X задает расположение буферов в дополнительной памяти.

Еще один способ организовать буферизацию ввода/вывода для жестких дисков — использовать драйвер SMARTDRV.SYS. Этот драйвер позволяет создать для диска кэш-память в расширенной или дополнительной памяти. Например, следующая строка в файле CONFIG.SYS определяет дисковый кэш размером 530 килобайтов, размещенный в расширенной памяти:

Кэш-память особенно эффективна при работе с базами данных, когда вам периодически требуется одна и та же информация. Если создать кэш-память достаточно большого размера, можно значительно сократить количество обращений к диску.

Если вы используете кэш-память для диска, не следует задавать оператор BUFFERS в файле CONFIG.SYS или пользоваться утилитой FASTOPEN , так как это приведет к многократной буферизации и вызовет излишние пересылки данных в оперативной памяти.

Буферизация данных имеет и свои недостатки. Если в результате аварии в питающей сети или по какой-то другой причине компьютер выключился, то информация, хранящаяся в буферах и не записанная на диск, будет потеряна.

При закрытии файла все буфера, связанные с ним, сбрасываются на диск. Если вам надо сбросить буфера, не закрывая файл, это можно сделать с помощью функции 68h прерывания INT 21h :

На входе: AH = 68h
BX = файловый индекс открытого файла
На выходе: AX = Код ошибки, если был установлен в 1 флаг переноса CF ;
0 , если операция выполнена успешно.

Дополнительно обновляется дескриптор файла в каталоге, а именно поля времени, даты и размера файла.

Обратите также внимание на функцию расширенного открытия файлов 6Ch , входящую в состав MS-DOS версии 4.0. Эта функция позволяет при открытии файла отменить буферизацию.

Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат многочисленные функции, использующие собственный механизм буферизации при работе с файлами. Их часто называют функциями потокового ввода/вывода. Такую буферизацию не следует путать с буферизацией, выполняемой операционной системой. Имена всех этих функций начинаются на f — fopen(), fclose(), fprintf() и т.д.

Функции потокового ввода/вывода хорошо описаны во многих учебных пособиях по языку программирования Си, поэтому мы приведем лишь краткий обзор этих функций, делая акцент на особенностях их применения.

При использовании функций потокового ввода/вывода файлы открываются функцией fopen() , закрываются функцией fclose() . Эти функции не только открывают и закрывают файлы (получают и освобождают их файловый индекс), но и, соответственно, создают и уничтожают структуру типа FILE , описанную в файле stdio.h и связанную с данным файлом:

Для организации потокового ввода/вывода вначале необходимо при помощи функции fopen() открыть файл. Функция fopen() имеет следующий прототип:

Первый параметр указывает на строку, содержащую путь открываемого файла, второй — на строку режима открытия файла. Возможны следующие режимы:

«r» файл открывается для чтения;
«w» файл открывается для записи;
«a» файл открывается для записи, данные будут добавляться в конец файла.

К буквам r, w, a справа могут добавляться буквы t и b .

Буква t означает, что файл будет открыт в текстовом режиме, b — в двоичном. Для двоичного режима не производится обработка таких символов, как конец строки, конец файла и т.д.

Строка режима открытия файла может дополнительно содержать символ ‘+’ . Этот символ означает, что для файла разрешены операции чтения и записи одновременно.

Для закрытия файлов, открытых для ввода/вывода потоком, должна использоваться функция fclose() :

При закрытии файла освобождаются и сбрасываются на диск все буфера, распределенные этому файлу.

Если вы открыли файл с помощью низкоуровневой функции open() , вы можете создать поток для этого файла, используя функцию fdopen():

В качестве первого параметра используется файловый индекс, полученный от функции open(), второй параметр аналогичен парметру mode для функции fopen() .

Для того чтобы закрыть поток, созданный функцией fdopen(), необходимо использовать функцию fclose() , а не close() .

Для открытого потока вы можете узнать файловый индекс с помощью функции fileno():

Функция возвращает файловый индекс, связанный с данным потоком.

Существуют потоки, соответствующие стандартным устройствам ввода, вывода, вывода сообщений об ошибках, стандартное устройство последовательного ввода/вывода и стандартное устройство печати. Для использования этих потоков не требуются процедуры открытия и закрытия. Для работы с потоками, соответствующими стандартным устройствам ввода/вывода, в функциях необходимо указывать:

stdin стандартное устройство ввода;
stdout стандартное устройство вывода;
stderr стандартное устройство для вывода сообщений об ошибках;
stdaux стандартное последовательное устройство ввода/вывода;
stdprn стандартное печатающее устройство.

Для работы со стандартными устройствами ввода/вывода в библиотеках трансляторов для языка программирования Си имеется соответствующий набор функций, которые должны быть вам хорошо известны — printf(), scanf(), putchar() и т.д.. Мы не будем их описывать для экономии места.

Приведем обзор функций, предназначенных для потокового ввода/вывода .

Для записи данных в поток предназначена функция fwrite() :

Эта функция записывает в файл stream блоки информации, каждый из которых имеет длину size байтов. Количество блоков — count . Данные для записи расположены по адресу buffer .

Если файл открыт в текстовом режиме, каждый символ возврата каретки CR заменяется на два символа — возврата каретки CR и перевода строки LF .

Функция возвращает количество действительно записанных блоков информации, без учета замены символа CR в текстовом режиме.

Чтение данных потоком можно выполнить с помощью функции fread() :

Эта функция используется аналогично предыдущей. Для распознавания конца файла и обнаружения ошибок после вызова этой функции необходимо использовать функции feof() и ferror().

Если при использовании функции fread() вы задали значения параметров size или count , равные нулю, функция fread() не изменяет содержимое буфера buffer .

Для позиционирования внутри файла, открытого потоком с помощью функции fopen() , предназначена функция fseek() :

В этой функции параметр offset задает новое содержимое указателя текущей позиции в файле stream , а параметр origin — определяет способ задания новой позиции. Этот оператор может иметь значения, аналогичные используемым в функции lseek() :

SEEK_SET Абсолютное смещение от начала файла
SEEK_CUR Смещение относительно текущей позиции
SEEK_END Смещение относительно конца файла

При открытии файла указатель текущей позиции устанавливается на начало файла. Операции ввода/вывода вызывают увеличение значения этого указателя на количество прочитанных/записанных байтов.

Функция fseek() позволяет вам установить указатель за конец файла, однако при попытке установаит указатель до начала файла функция возвратит признак ошибки — ненулевое значение.

При использовании функции fseek() для позиционирования внутри файлов, открытых в текстовом режиме, необходимо учитывать особенность обработки текстовых файлов — автоматическую замену символа возврата каретки CR на пару символов: возврат каретки CR и перевод строки LF . Для текстовых файлов функция fseek() будет правильно работать только в следующих двух случаях:

  • поиск со смещением offset , равным нулю, при любом значении параметра origin ;
  • поиск выполняется относительно начала файла, причем в качестве смещения offset используется значение, полученное специальной функцией ftell() .

Функция ftell() возвращает текущее значение указателя позиции для файла, или -1 при ошибке:


Пара функций ftell() — fseek() позволит вам правильно организовать позиционирование для файлов, открытых в текстовом режиме.

Есть еще одна возможность организовать позиционирование внутри файлов, открытых потоком — использовать пару функций fgetpos() — fsetpos() :

Эти две функции используют для запоминания и установки позиции переменную с типом fpos_t, определенным в файле stdio.h. Функция fgetpos() записывает в эту переменную текущую позицию в потоке stream . Содержимое переменной затем может быть использовано для установки позиции в потоке с помощью функции fsetpos().

Обе эти функции возвращают нулевое значение в случае успешного завершения работы, или ненулевое — при ошибке.

Среди функций потокового ввода/вывода можно выделить группу функций форматного ввода/вывода. Это такие функции, как fputc(), fgetc(), fputs(), fgets(), fprintf(), fscanf() .

Функции форматного ввода/вывода сильно облегчают запись/чтение таких элементов данных, как отдельные байты, текстовые строки, числа в различных форматах.

Для записи в поток отдельных байтов используется функция fputc():

Байт c записывается в файл stream начиная с текущей позиции. После записи текущая позиция увеличивается на единицу. Функция возвращает записываемый байт или значение EOF , которое служит признаком ошибки.

Для побайтового чтения содержимого файла, открытого потоком, удобно использовать функцию fgetc():

Эта функция возвращает считанный из файла и преобразованный к типу int байт из потока stream . После чтения байта текущая позиция в файле увеличивается на единицу.

При достижении конца файла или в случае ошибок функция fgetc() возвращает значение EOF . Однако для проверки на ошибку или конец файла лучше пользоваться специальными функциями ferror() и feof() . Если вы открыли файл в двоичном режиме, единственный способ определить момент достижения конца файла — использовать функцию feof() , так как значение константы EOF может находиться в любом месте двоичного файла.

Для работы со строками предназначены функции fputs() и fgets() .

Функция fputs() предназначена для вывода строки в файл, открытый потоком:

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

Для ввода строк из текстового файла удобна функция fgets():

Функция читает байты из потока stream и записывает их в буфер string до тех пор, пока не произойдет одно из двух событий — будет прочитан символ новой строки ‘n’ или количество прочитанных символов не будет равно n-1 .

После того, как байты будут прочитаны в буфер, в конец образованной из этих байтов строки функция записывает двоичный ноль. Если был прочитан символ новой строки ‘n’ , он тоже записывается в буфер.

Для анализа достижения конца файла или ошибок необходимо использовать функции feof() и ferror() .

Для форматного вывода в файл содержимого переменных удобно использовать функцию fprintf() :

Эта функция аналогична хорошо известной вам функции форматного вывода на экран printf(), с которой обычно начинают изучение языка программирования Си. Вспомните такую программу:

Функция fprintf() имеет дополнительно один параметр — stream , который определяет выходной файл.

После завершения работы функция возвращает количество записанных байтов или отрицательную величину, если при записи произошла ошибка.

Для форматного ввода информации из файла можно использовать функцию fscanf() , аналогичную известной вам функции scanf():

Эта функция читает данные, начиная с текущей позиции в потоке stream , в переменные, определенные аргументами arg . Каждый аргумент должен являться указателем на переменную, соответствующую типу, определенному в строке формата format .

Функция fscanf() возвращает количество успешно считанных и преобразованных в указанный формат полей. Те поля, которые были считаны, но не преобразовывались, в возвращаемом функцией значении не учитываются.

При достижении конца файла функция возвращает значение EOF . Если функция возвратила нулевое значение, это означает, что преобразование полей не производилось.

Рассмотрим теперь функции, управляющие буферизацией для потокового ввода/вывода.

Функция setbuf() позволяет вам заменить системный буфер на свой собственный:

Параметр buffer должен указывать на подготовленный пользователем массив, имеющий размер BUFSIZ байтов. Константа BUFSIZ описана в файле stdio.h.

Функция setvbuf() позволяет программе не только указать свой буфер, но и задать его размер:

Параметр stream должен указывать на открытый поток, причем для этого потока до вызова функции setvbuf() нельзя выполнять операции чтения/записи.

Параметр buffer должен указыват на подготовленный программой буфер размером size байтов. Этот буфер будет использоваться для работы с потоком stream .

Параметр mode может иметь значения _IOFBF, _IOLBF, _IONBF . Если mode равно _IOFBF или _IOLBF , параметр size указывает размер буфера. Если параметр mode равен _IONBF , буферизация не используется, парметры buffer и size игнорируются.

Параметры _IOFBF и _IOLBF эквивалентны.

Если в качестве адреса буфера buffer задать значение NULL , функция автоматически закажет буфер размером size .

Функция setvbuf() возвращает ноль при успешном завершении и ненулевую величину, если указан неправильный парметр mode или неправильный размер буфера size .

Для чего может понадобиться изменение размера буфера?

Главным образом — для сокращения времени, необходимого для позиционирования магнитных головок при выполнении операций одновременно над несколькими файлами, например, при копировании файлов, слиянии нескольких файлов в один и т.д.

При закрытии потока функцией fclose() содержимое буфера записывается на диск. Если программе необходимо выполнить запись содержимого буфера на диск без закрытия файла, она может воспользоваться функцией fflush():

Эта функция возвращает ноль при успешной записи буфера на диск, а так же в тех случаях, когда поток либо совсем не имеет буферов, либо открыт только для чтения. При ошибке возвращается значение EOF .

Если поток открыт только для чтения, функция fflush() очищает содержимое буфера, связанного с этим потоком.

В качестве примера приведем текст программы, копирующей содержимое текстового файла. Программа копирует этот файл три раза. В первый раз одна использует буфер стандартного размера, затем увеличивает размер буфера в десять раз, и, наконец, копирует файл без использования механизма буферизации. Каждый раз программа измеряет продолжительность копирования файла с помощью функции clock() , входящей в состав стандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0.

В задачу данной книги не входит описание всех функций стандартных библиотек трансляторов Microsoft QC 2.5 и C 6.0, предназначенных для работы с дисками и файловой системой. Но мы приведем еще несколько интересных и полезных на наш взгляд функций.

Как мы уже отметили, программа может использовать два режима ввода/вывода для файлов — текстовый и двоичный. Для переключения этого режима для открытого файла можно использовать функцию setmode():

Первый параметр — файловый индекс. Второй параметр может принимать два значения:

O_TEXT установить текстовый режим;
O_BINARY установить двоичный режим.

Функция setmode() должна вызываться перед началом ввода/вывода в открытый файл.

Мы рассказывали о позиционировании внутри файла. Если вам нужно просто установить указатель позиции на начало файла, открытого для потокового ввода/вывода, вы можете воспользоваться функцией rewind():

Если вам нужно переназначить ввод/вывод для стандартных устройств (потоков stdin, stdout, stderr ), вы можете использовать функцию freopen() :

Функция freopen() закрывает файл, с которым был связан поток stream , и переназначает этот поток файлу, определенному параметром filename . Параметр mode задается так же, как и для функции fopen() .

Можно переназначить файловый индекс для файла, открытого функцией open() . Для этого можно воспользоваться одной из двух функций — dup() или dup2() :

Первая функция связывает с открытым файлом еще один файловый индекс. Этот индекс она возвращает при успешном завершении. В случае ошибки она возвращает значение -1 .

Новый файловый индекс может быть использован для любых операций над файлом.

Функция dup2() переназначает файловый индекс handle2 , связывая его с тем же файлом, которому соответствует файловый индекс handle1 . Если во время вызова функции dup2() с файловым индексом handle2 связан какой-либо открытый файл, этот файл закрывается. В случае успешного завершения функция dup2() возвращает нулевое значение. Если произошла ошибка, возвращается значение -1 .

В первой книге при описании векторной таблицы связи мы говорили о том, что для всех открытых файлов MS-DOS хранит различную информацию в специальной таблице. Ее адрес находится в поле file_tab векторной таблицы связи.

В этой таблице для каждого открытого файла хранится информация о количестве файловых индексов ( file handle ), связанных с данным файлом, режиме открытия файла (чтение, запись и т.д.), слово информации об устройстве, указатель на заголовок драйвера, обслуживающего данное устройство, элемент дескриптора файла (дата, время, имя файла, номер начального кластера, распределенного файлу), номер последнего прочитанного кластера и т.д.

Теперь, когда вы изучили способы работы с файлами, имеет смысл еще раз вернуться к разделу, посвященному таблице открытых файлов.

Вы можете самостоятельно экспериментировать с этой таблицей. Можно, например, попробовать создать несколько файловых индексов для какого-либо файла и посмотреть после этого содержимое поля, в котором находится количество файловых индексов, связанных с данным файлом.

Можно попробовать организовать чтение файла порциями размером в один кластер, при этом каждый раз выводить содержимое поля, в котором находится номер последнего прочитанного кластера. Это один из самых простых способов получить список кластеров, распределенных данному файлу.

Однако не обольщайтесь — все что связано с таблицей файлов, отсутствует в документации по операционной системе MS-DOS. Используя эту таблицу для определения списка кластеров или для каких-либо других целей, вы рискуете потерять совместимость с последующими версиями операционной системы.

Запуск старых DOS программ под Windows x64

В любой организации может оказаться так, что при обновлении старых компьютеров на новые можно столкнуться с таким фактом, что компьютеры новые, но необходимость использования старых программ никуда не отпала. А одной из старых программ вполне может оказаться какое-нибудь приложение, написанное в 90ые года под MS-DOS, которое напрочь отказывается запускаться на современных операционных системах. В таком случае очень помогает эмулятор MS-DOS под названием DOSBox, использованию которого и посвящена эта статья.

Скачиваем последнюю версию с официального сайта , после устанавливаем. Никаких необычных действий при установке программы не требуется.

Теперь ищем необходимую вам DOS программу. Допустим она располагается на диске D в папке Prog и называется Prog.exe. Переходим в эту папку, и создаем там текстовый файл с любым названием и расширением conf. В него пишем:

  • mount c D:\Prog — монтирует в эмулятор папку D:\Prog как раздел жесткого диска С;
  • c: — осуществляет переход на раздел C жесткого диска;
  • Prog.exe — запускает нужную программу. Вместо exe файла могут быть так же файлы с расширением bat или pif.
  • exit — закрывает DOSBox после завершения работы программы. Работает ТОЛЬКО с exe файлами.

Если вам нужно, чтобы DOSBox закрывался после запуска bat файла, то вместо простого запуска prog.bat пишем:

Теперь создаем еще один текстовый файл с расширением bat. В него пишем:

Вместо «C:\Program Files (x86)\DOSBox-0.74» указываем тот путь, куда была установлена программа DOSBox. Вместо D:\Prog указываем путь к нужной DOS программе, и вместо prog.conf указываем имя файла, созданного выше.
Сохраняем, и пробуем запустить. Если все прошло успешно, то появится окошко DOSBox, в котором запустится нужная программа.

Впрочем, момент триумфа может омрачить полное отсутствие русского языка — но это дело поправимое.
Для начала скачиваем с официального сайта официальную локализацию — после чего распаковываем содержимое архива в каталог с программой. Теперь открываем созданный выше conf файл, и дописываем туда в самый верх следующее:

Где «C:\Program Files (x86)\DOSBox-0.74\russian.txt» — это путь к распакованному в папку с программой файлу russian.txt.

Сохраняем и пробуем запустить программу.

Теперь русские символы отображаются и печатаются.

Если при запуске программы смущает второе окошко DOSBox, которое открывается вместе с основным окном, то можно в bat файл дописать параметр -noconsole, в итоге bat файл для запуска приобритет следующий вид:

Другие статьи:

Комментарии:

    • bsm
    • 10.11.2020 00:29

    Здравствуйте. Установил DOSBox-0.74-3. В каталоге F:\test.DOSBox создал файлы,-
    test.bat:

    rem test.bat
    rem
    start «» «C:\Program Files (x86)\DOSBox-0.74-3\DOSBox.exe» -conf «F:\test.DOSBox\test.conf» -noconsole

    [dosbox]
    language=»C:\Program Files (x86)\DOSBox-0.74-3\russian.txt»
    memsize=1024

    [dos]
    keyboardlayout=RU
    FILES=250

    [autoexec]
    mount T F:\test.DOSBox
    T:
    T:\DN-DPMI\DN.com

    После запуска test.bat запускается пустое окно DOSBox и через некоторое время закрывается. Как говорит stdout.txt,-

    DOSBox version 0.74-3
    Copyright 2002-2020 DOSBox Team, published under GNU GPL.

    CONFIG:Loading primary settings from config file F:\test.DOSBox\test.conf
    Exit to error: MSG:Can’t load messages: F:\test.DOSBox\»C:\Program Files (x86)\DOSBox-0.74-3\russian.txt»

    Как исправить ситуацию? Спасибо.

    А файл локализации был скачан? Судя по логу, программа просто не может его загрузить. Еще, желательно попробовать в конфиге указать просто название файла локализации, а не целый путь, т. е.:

    Да, файл локализации имеется.

    Согл. файла конфигурации, файл локализации должен браться с
    language=»C:\Program Files (x86)\DOSBox-0.74-3\russian.txt»
    а DOSBox пытается взять его с F:\test.DOSBox\»C:\Program Files (x86)\DOSBox-0.74-3\russian.txt»

    У меня авторская досовская программа не открывается на windows 8. Что можно сделать?

    Может быть, при этом пишутся какие-то ошибки? Сложно определить в чем проблема, особенно если речь идет о какой-то уникальной программе.

    У меня всё сразу получилось. Программа работает. НО. Не просто медленно — УЖАСАЮЩЕ медленно!
    На обработку 1-й (!) обычной текстовой строки из Блокнота (просмотр и вылов заданных слов) уходит почти 1 (!) секунда. И -cycles=max не помогает. А у меня обычно сотни и тысячи строк. Придётся теперь продавать только что купленный комп 64-bit и покупать 32-ку. :(

    Дополняю (жаль, что нельзя здесь скриншот), в заголовке окна стоит:
    DOSBox 0.74-3, Cpu speed 3000 cycles, Frameskip 0, Program: FOXPROL

    УРРРРРРААААА! Просто я, балбес, по аналогии с -console в .bat занёс туда же и max. А надо же в .conf.
    Всё работает, и не так уж и медленно, очень даже терпимо.
    Большущее Вам спасибище.

    С огромным уважением, Владимир Марциновский

    Извините за вопрос! А где именно взять русскую локализацию? новичок, сильно не пинайте плииз :)

    нашёл где :) http://www.dosbox.com/tools/DOSBox-russian-lang-074.zip
    Но мне не помогло! Окно просто закрывается и дальше тишина! мой конфиг выглядит так
    [autoexec]
    mount c F:\Realizacia
    c:
    C:FOXPRO25\FOXPROx.EXE -T C:\real\uprprg.prg
    exit

    Всё разобрался сам спасибо! :)

    Может немного тупой совет, но не ставьте пробелов в названии папки с игрой, иначе работать не будет. Думаю, те, кто впервые работает с DOS-системой могут этого не знать.

    Можно ли увеличить размер окна, в котором
    запускается DOS-программа?

    Самый простой способ — нажать Alt+Enter для того, чтобы окно раскрылось на весь экран.

    чуть не в тему, но до установки некоего обновления и Win’7 64x, и Win’10 64x нормально работают с DOS-программой, с ее графикой. Какое-то обновление «гробит» эмулятор.. — можно что-то исправить?

    Не так давно вышла новая версия DOSBox (в сентябре 2020) — попробуйте протестировать её в работе.

    Программа супер, но есть нюанс, при раскрытии окна на полный экран (Alt-Enter), размер отображения досовской программы остается прежний, хотя DosBox растягивается на весь экран (заливая черным оставшуюся часть окна). Есть ли возможность «растянуть» окно именно дос программы?

    Попробуйте добавить в конфиг следующие строки:

    У меня та же проблема, что и у Светланы из комментария:
    «Светлана 19.12.2020 09:12
    При запуске программы в DOSBOX выходит сообщение: «This program must be run under Win32″. Можно как то это победить? Стоит Windows7 x64.»
    После установки DOSBOX я установила в него win3.11, но как воспользоваться win3.11 для запуска нужной мне программы не знаю. Может быть Вы знаете, как это сделать?

    В вашем случае, вам нет нужды использовать DOSBox, так как вы пытаетесь запустить исполняемый файл Windows — в среде DOS он просто работать не будет.

    Попробуйте запустить его прямо в основной операционной системе, используя различные параметры совместимости (правой кнопкой мыши — Свойства — Совместимость), а если не получится — смотрите в сторону виртуальных машин с Windows XP.

    После запуска программы в каталоге создаются 2 файла
    Stdout и stderr

    Stderr.txt он пустой

    Stdout с таким содержимым

    Файлы эти создаются и при запуске foxpro и fox26x и отличаются только
    строкой с предупреждением.
    Где искать проблему?

    можно ли в досбоксе зашарить файлы по сети для совмместной работы с базой данных с другими компьютерами? несколько лет назад пробовал в убунту — любой один комп работает с БД, а если одновременно, то не получается. похоже типо как на отсутствие команды шары в ДОСе.

    Если вопрос о том, может ли DOS создать общую папку, то да, но для этого потребуется большое количество действий. Другое дело, что далеко не факт, что сама программа и её БД позволяет работать с собой сразу нескольким людям.

    сама программа шарит БД совместно с другими по сети на win95-98/nt/xp — автоматически, никаких спец. действий для этогог не нужно, кроме объявления сетевых ресурсов (в «чистом» ДОСе для совместной работы с файлами требовалась команда share). а вот как с этим в досбоксе?

    Судя по зарубежным форумам, шары в DOSBox не поддерживаются, но поддерживаются в его аналоге vDOS — https://sourceforge.net/projects/vdos

    Никак. В dosbox невозможно поставить клиент Microsoft Network (всё упирается в общем-то в отсутствие config.sys)
    Но можно подключить сетевые ресурсы дисками в хост-системе, а в досбоксе смонтировать их как диски — никаких проблем, и даже эмуляций NE2000 не требуется.
    Ну или использовать что-то другое: vDOS, FreeDOS на VirtualBox и т.п.

    Программа работает под Foxpro .а под Fox26x вылетает по ошибке

    Warning: file creation failed: p:\50507648.TMP
    Что делать?


    А такой файл существует? Убедитесь, что если он существует, то не имеет атрибутов «скрытый» или «только чтение».

    нет , такого файла не нашлось! А теоретически должна работать под fox26x?

    Работать то должна, другое дело, что лично самому такой софт разворачивать мне не приходилось. Но на всякий случай покажите свой конфиг, может быть проблема в нем.

    А диск «p:» то в досбоксе прописан?

    Замечательная программа , но возникла такая проблема.Если запускаемая программа написана на FOXPRO , то все хорошо работает на 64.Если же на Fox26x , То запускается , а потом ошибка и вылетает.Помогите разобраться
    Ошибка Warning: file creation failed: p:\50507648.TMP

    Есть у вас на компе стоит, 64-ти разрядная Windows 8 или 10, то имеет смысл установить этот эмулятор DOS. Потому, что опытные компьютарщики знают, что «старые добрые» досовские программы, универсальные и среди них, есть такие которые, до сих пор нельзя заменить, аналогами для Windows

    Recluse, подскажите пожалуйста как заставить программу dosbox работать с моим com1 (настоящий последовательный порт). На virtualbox я разобрался как «пробросить» Com1, а тут мне не понятно есть ли такая возможность вообще. Программа работает, но связи нет. Win10 X64 pro.

    В конфиг нужно добавить:
    serial1=directserial realport:com1
    вместо directserial может быть dummy, modem, nullmodem, при этом для остальных значений параметр realport не нужен. Подробнее можно прочесть на английском языке тут .

    Программа лежит на диске D:\top. Конфиг:
    [dosbox]
    «C:\Program Files (x86)\DOSBox-0.74\russian.txt»
    [dos]
    keyboardlayout=RU
    [autoexec]
    mount c D:\top
    c:
    call top.exe
    exit
    Программа запускается, но не видит базу с настройками, которая лежит в d:\top\DB\. Как пофиксить?

    Возможно в программе есть какие-то настройки, которые стоит изменить для работы по новому пути?

    Например, программа до этого была по пути C:\top, но сейчас просто находится по адресу C:\, и пытается обратиться по пути C:\top\DB.

    В разделе [dosbox] указывать на файл настроек русского языка надо так:
    language=«C:\Program Files (x86)\DOSBox-0.74\russian.txt»
    а не просто название файла.

    Кажется, я нашел подходящий вариант.
    Вместе с DOSBOX (для обеспечения работы программы) надо использовать SPRINT (для обеспечения печати). Конечно, некоторые формы выглядят не так, как задумывались или как привыкли пользователи на протяжении многих лет (есть эффект сжатия и сдвига налево, тогда как есть достаточно много места до низа страницы и правого края), но когда северный пушной зверек появится на пороге, сгодится и так.

    У меня два вопроса по использованию dosbox.
    1) Каким образом можно поставить максимальное быстродействие исполняемой программы (не игра)? На WinXP формирование некоего отчета занимает минуту (усредненно), а в Win7 под dosbox — минут 15, или больше. Ctrl+F12 ускоряет, но не намного, до 13-14 минут максимум. Даже при формировании этого самого отчета видно, как медленно ползут проценты, нажатие Ctrl+F12 ускоряет, ускоряет, но потом опять замедляет.

    2) Насчет распечатки. Программа, о которой я писал выше, может печатать и на LPT порт, и на USB. Но LPT принтеров уже нет, а при команде печатать на USB результат нулевой, оно и понятно, во времена DOS-а такого порта не было. Есть какой-то вариант непосредственной печати (кроме как сохранить файл и напечатать стандартными средствами Windows)?

    Каким образом можно поставить максимальное быстродействие исполняемой программы (не игра)?

    Попробуйте добавить в конфиг следующую строчку — cycles=max . После этого DOSBox должен обеспечить максимально возможную производительность.

    Попробуйте скачать модифицированную версию DOSBox отсюда — http://ykhwong.x-y.net/ . Затем, в конфиг добавьте это:

    Здравствуйте!
    Спасибо большое за ответы.
    С производительностью ясно. При установке cycles=max действительно программа работает наиболее быстро (хотя до работы под WinXP далеко), но ясно, что это тот максимум, на который способна эмуляция.
    С печатью тоже получилось. Но.
    1) Печатается нерусскими буквами, как подгрузить в принтер кириллицу?
    2) При второй или третьей посылке задания на печать — синий экран смерти.
    3) Если документ, посылаемый на печать, в ширину больше 80 символов, то остальные переносятся на вторую и даже третью строку. Есть ли вариант применения управляющих последовательностей — чтобы печатать полусжатым, сжатым или суперсжатым методом, а также задавать ориентацию — книжную или альбомную?

    Ох, это очень тяжелый вопрос, так как с необходимостью печати из DOSBox мне не доводилось сталкиваться. Сохранение в файл, и печать из него действительно не вариант?

    Как вариант — вариант ))))
    Собственно, кое-какие пользователи так сейчас и поступают. Те, которые не пожелали понизить версию с семерки или десятки на WinXP. Потому что программа широко распространена в узких кругах, аналога ей нет (или будет стоить очень дорого). Те, которые печатают раз в месяц какие-то итоговые отчеты на 5 страницах.
    Но если дело дойдет до центрального офиса, где десяток пользователей печатают каждый день по 50 страниц, и до того ближайшего или далекого будущего, когда образуется нехватка компьютеров под 32-разрядной XP, а продаваться будут только 64-разрядные, то хотелось бы знать, насколько реальна штатная работа под DOSBOX с регулярной и частой печатью?

    К сожалению, на этот вопрос я не могу дать квалифицированный ответ.

    Однако, могу предложить вам посмотреть в сторону виртуальных машин — бесплатных программ более чем достаточно. Если ваша программа без проблем работает например под Windows XP, то можете просто создать виртуальную машину, сделать автозапуск своей программы в ней, расшарить на компьютере-хосте принтер, и подключится на него с виртуальной машины.

    Спасибо! запустилась с первого раза! Много проблем отпало! Рулит на Windows 10 64 bit!

    отличная статья, со второй попытки запустил ностальгический EOB1 ;)
    Единственно (но могу ошибаться), если в папке два исполняемых файла, то в conf надо вписывать их оба

    При запуске программы в DOSBOX выходит сообщение: «This program must be run under Win32». Можно как то это победить? Стоит Windows7 x64.

    Судя по всему вы пытаетесь запустить исполняемый файл, который предназначен для работы в Windows, а не в MS DOS. Попробуйте запустить программу прямо из под Windows, хотя не исключено, что под Windows 7, да и к тому же 64 разрядной, она нормально работать не будет.

    А можно как-нибудь сделать, чтобы сама DosBox монтировалась не в диск Z:, а какой-нибудь другой? Дело в том, что в самой моей ДОС-программе базы прописаны именно на диске Z, а получается, что я его не могу смонтировать в файле conf, так как эта буква уже занята самой программой.

    Без перекомпиляции исполняемого файла DOSBox такое проделать невозможно.

    Большое спасибо. Все получилось.
    В dosbox.conf добавил FILES=250,
    и перед запуском программы, запускаю KEYRUS.COM.
    Программа стала работать.

    Юрий, каким ехе пользуетесь скачанным с офиц. сайта DosBox или по ссылке предложенной выше?

    Доброго времени суток!
    Программа СУБД написана на Foxpro 2.6 DOS.
    Программа открывает много таблиц.
    При запуске программы из-под DOSBOX
    возникает ошибка «Too many files open» (Слишком много открытых файлов.).
    При запуске программы в 32-х разрядной системы, без DOSBOX,
    в C:\Windows\System32\config.nt
    записывал files=250 и программа работала.
    Где и как можно в DOSBOX указать количество открываемых файлов?

    К сожалению, судя по всему, без правки исходных кодов DOSBox это не сделать, однако есть в интернете люди, которые столкнулись с этой же проблемой. Есть и решение — модифицированный исполняемый DOXBox.exe, который можно скачать здесь . Предупреждаю — используйте на свой страх и риск — проверить работу данного файла нет возможности.

    Доброго времени суток!
    DOSBox — замечательная программа, даже принтер порта LPT на USB печатает, но есть для меня один БОООООЛЬШУЩИЙ минус. запускаемая прога написана на CLIPPER, и почему-то в среде DOSBox неимоверно долго открываются файлы баз данных. параметр FILES=60. Может сталкивался кто?

    По пути D:\UCHET есть папка с таким же названием — Uchet? Если нет, то попробуйте скопировать данный bat файл в корень диска D, и запустить его оттуда.

    А что внутри Uchet.bat?

    Сложно сказать, что в вашем случае пошло не так, но если вы выложите содержимое файлов конфигурации и bat файла, то возможно я смогу вам помочь.

    Все делал по инструкции, запускается Dosbox и тут же закрывается, в чем может быть проблема. система Win 7×64.

    Подскажите что делать, если у запущенной программы в DOS поехали шрифты все, как их поменять?

    А что подразумевается «поехавшие шрифты»? Если вместо русского языка отображаются различные загогулины, то в статье есть решение.

    Пытаемся загрузить БД с перечнем людей, сделали все, что указанно в инструкции. Но при запуске эмулятора он выключается и ничего не происходит. Интерфейс этой БД очень похож на FAR Manager, вот и подумал, что он тоже может быть связан с запуском.

    Уважаемый Recluse и остальные знающие, как заставить работать F1-10 клавиши?

    Что пытаетесь запустить?
    Если FAR Manager, то он не является MS-DOS программой.

    Уважаемые знатоки! Сделал все по инструкции, но результата это не принесло. Вместо запуска голубого окна эмулятор просто закрывается. Что я делаю не так? Может ли программа MS-DOS запускаться через другую, FAR?

    Попробуйте после строки

    Подразумеваю, что у вас есть дисковод, которому в системе присвоена буква A (по умолчанию), и в него вставлена нужная дискета.

    А мне тоже страсть как нужно запустить дос-прожку, но загогулина в том, что она записана на ключевой к дискете, к которой постоянно обращается в процессе работы. Как быть?

    Для Алексея:
    А какой смысл под 32 разрядной ХР запускать DOSbox ? ХР вполне сносно исполняет большинство досовских программ и доступ к компорту будет прямой.
    С DOS программами не было проблем и в Win7 32.
    DOSbox необходим при наличии 64-битной системы

    Это очень странно, но я сомневаюсь, что проблема в самом DOSBox. Видит ли программа нормально саму базу? Находится ли файл базы в той же директории, что и сама программа? Желательно было бы еще и конфиг DOSBox посмотреть, который используется для работы с программой.

    Здравствуйте, подскажите пожалуйста, в чем может быть проблема, DOS приложение нормально запускается через DosBox но при работе не функционируют часть кнопок, например в программе есть возможность индексации базы данных и при попытке выполнить индексацию ничего не происходит, так же при работе в базе данных не открывается некоторые окна. Никаких ошибок при этом не показывается. Есть ли какие нибудь настройки в DOSBox касающиеся работы с БД? Спасибо.

    Покажите ту часть настроек/конфига, в которой прокидывается com порт из реальной системы в эмулируемую.

    Может быть кто-то подскажет.
    Программа для DOS работала через com-порт с медицинским прибором.
    Запустить программу через Dosbox получилось (через графическую оболочку D-Fend Reloaded), доступ в архив программы есть, но получать данные с устройства не получается. Номер порта и прерывание установил вроде бы правильно. Система Windows XP 32-битная.
    Очень извиняюсь, что не совсем соответствует теме.
    Заранее огромное спасибо за помощь.

    Спасибо большое, получилось, правда с трудом и с нюансами. Попробую описать. После ввода рекомендованной Вами добавки, нажимаю Enter — ничего, жду сек 30, опять на всякий случай жму Еnter — появляется пустое голубоватое окошко, жду и примерно через минуту запускается программа. Если бы не ждал,то и не узнал бы. Проделал ту же операцию с другой программой. Без добавки она тоже не запускалась, но с добавкой открылась и гораздо быстрее. Но есть еще такие трудности. Добавка не сохраняется и ее надо вводить при каждой попытке запуска. Закрыть запущенную программу удается или введя команду exit через диспетчер задач — движение курсора мыши ограничено и до строки с крестом закрытия он не достает.
    Но все равно,большое спасибо!

    Если честно, то с трудом представляю, что могло пойти не так, так как вроде все в файлах указано верно.
    Могу предложить выполнить в окне DOSBox следующие команды из файла st.conf:

    mount c E:\CHESS2
    c:
    CG3.exe

    И посмотреть, запустится ли программа.

    Извините, ошибка в предыдущем коментарии — программа лежит на диске E, а не на D

    Здравствуйте, уважаемый Rrecluse!
    Спасибо за Ваш быстрый ответ. Я скопировал путь из проводника и теперь после запуска bat файла открывается вот такое окно DOSBox (ссылка http://take.ms/iWGID ), но нужный мне DOS файл не запускается. Проверьте, пожалуйста, мои 2 файла.
    Нужная мне программа CESS2 лежит на диске D, исполняемый файл CG3.exe.
    Первый файл st.conf

    Ниже bat файл Chess.bat

    Надеюсь на Вашу помощь.
    Спасибо

    Судя по тексту ошибки, у вас нету файла DOSBox.exe по пути C:\Program Files (x86)\DOSBox-0.74 . Попробуйте перейти в эту папку через Проводник, и скопировать через него путь к исполняемому файлу DOSBox в bat файл.

    Здравствуйте, уважаемый Recluse.
    У меня после запуска bat файла появляется вот такое окошко (ссылка на скриншот http://take.ms/12ZLK ). Странно, DOSBox лежит в папке Program File, а его .exe файл почему-то Windows 10 не видит? В чем тут может быть дело? Подскажите, пожалуйста.
    И еще, в Вашем последнем ответе на комментарий от 10.02 Вы вроде бы исправляете какую-то ошибку в bat файле, но я не увидел никакой разницы в записях:
    (» вместо C:\Program Files (x86)\DOSBox-0.74 должен быть просто C:\Program Files (x86)\DOSBox-0.74.»). Возможно тут опять какая-то неточность?
    Спасибо

    Для 32-разрядных систем путь по умолчанию к программе в bat файле будет немного другой — вместо C:\Program Files (x86)\DOSBox-0.74 должен быть просто C:\Program Files (x86)\DOSBox-0.74 .

    Всем привет! Эта программа и все процедуры будут действовать для 32-х разрядной системы? А то вроде все правильно, а в итоге все закрывается( Если нет то как мне быть кто подскажет.

    Спасибо! Скопировала файлы russian.txt и dosbox.conf в папку с программой, которую нужно запустить и написала в файле conf

    Все заработало. Еще раз спасибо.

    Попробуйте в файле conf написать следующее (вместо того, что было в статье):

    Ну и стоит убедиться в наличии файла russian.txt в папке DOSBox.

    Добрый день! У меня почему-то не получается сделать русский язык. Все сделала как сказано. После добавления в conf-файл

    открывается только черное окошко, программа не загружается и через несколько секунд окно закрывается.
    Без этого открывается, но с иероглифами. Подскажите, пожалуйста, что не так.

    Самое простое, что мне приходит на ум, это попробовать сделать символическую ссылку, например через программу Link Shell Extension. О том, как ей пользоваться можно почитать в этой статье —

    Т. е. попробовать сделать ссылку с файлом/папки базы в ту директорию, которая монтируется в DOSBox.

    Программа DOS пытается открыть базу данных из другого каталога и выходит ошибка о невозможности открыть данный файл. Если я правильно понял программа запускается в dosbox на вирт. диске и доступ к другим ресурсам получается недоступен. Как подключить внешние данные причем с сохранением пути?

    Не совсем в курсе, что подразумевается под «BD», не могли бы вы поподробнее рассказать про это?

    Как настроить загрузку необходимых BD, если они в другом каталоге?

    У меня всё отлично заработало. Даже с CLS поэкспериментировал, чтоб удалять мусор из КС. Автор, спасибо за помощь. Ты отличный человек)
    К сведению: Windows 7 ultimate 64x. Проблем не возникло.
    Ребят проверяйте себя лучше. Вероятнее всего сами допустили ошибку.
    Пишите, подскажу, если что alexxx.merc@gmail.com

    Да, в статье была допущена небольшая ошибка. Попробуйте исправить свой bat файл на то, что сейчас в статье.

    Та же ерунда, что и у предыдущего пользователя/

    Здравствуйте!
    При попытки запустить бат файл он пишет ошибку; Не удается найти «-conf». Проверьте, правильно ли указанно имя и повторите попытку.
    Проверял правильность заполнения созданных мною файлов несколько раз и ошибок не увидел.

    DOS Fn 4cH: завершить программу — EXIT

    Выход

    Вход

    DOS Fn 4bH: выполнить или загрузить программу — EXEC

    Выход

    Вход

    DOS Fn 4aH: Сжать или расширить блок памяти

    Выход

    Вход

    • AH = 49H
    • ES = сегментный адрес (параграф) освобождаемого блока памяти
    • AX = код ошибки если CF установлен

    Описание:

    Освобождает блок памяти, начинающийся с адреса ES:0000. этот блок становится доступным для других запросов системы. Вообще говоря, вы должны освобождать лишь те блоки памяти, которые вы получили через функцию 48H распределить память. Родитель отвечает за освобождение памяти порожденных процессов. Тем не менее, ничто не препятствует вам освобождать память чужих проыессов.

    • AH = 4aH
    • ES = сегмент распределенного блока памяти
    • BX = желаемый размер блока в 16-байтовых параграфах
    • AX = код ошибки если CF установлен
    • BX = наибольший доступный блок (если расширение неудачно)

    Описание:

    Изменяет размер существующего блока памяти. Когда программа получает управление, функция 4bH EXEC уже распределила блок памяти, начиная с PSP, который содержит всю доступную память. чтобы освободить память для запуска порождаемых процессов, блок памяти, начинающийся с PSP, необходимо сначала сжать.

    Замечание:

    функция 31H (KEEP) и INT 27H (TSR) сжимают блок по адресу PSP.

    • AH = 4bH
    • DS:DX = адрес строки ASCIIZ с именем файла, содержащего программу
    • ES:BX = адрес EPB (EXEC Parameter Block — блока параметров EXEC)
    • AL = 0 = загрузить и выполнить
    • AL = 3 = загрузить программный оверлей
    • AX = код ошибки если CF установлен

    Описание:

    предоставляет средства одной программе (родителю) вызвать другую программу (ребенка), которая по завершению возвратит управление родителю.

    DS:DX указывает на строку ASCIIZ в форме: «d:путьимяфайла»,0. если диск или путь опущены, они подразумеваются по умолчанию.

    ES:BX указывает на блок памяти, подготовленный как EPB, формат которого зависит от запрошенной подфункции в AL.

    AL=0 EXEC: так как родительская программа первоначально получает всю доступную память в свое распоряжение, вы должны освободить часть памяти через функцию 4aH до вызова EXEC (AL=0). обычная последовательность:

    1. Вызовите функцию 4aH с ES=сегменту PSP и BX=минимальному объему памяти, требуемой вашей программе (в параграфах).

    2. Подготовьте строку ASCIIZ с именем вызываемого программного файла и установите DS:DX на первый символ этой строки.

    3. Подготовьте блок параметров EXEC со всеми необходимыми полями.

    4. Сохраните текущие значения SS, SP, DS, ES и DTA в переменных, адресуемых через регистр CS (CS — это единственная точка для ссылок после того, как EXEC вернет управление от ребенка).

    5. Выдайте вызов EXEC с AL=0.

    6. Восстановите локальные значения SS и SP.

    7. Проверьте флаг CF, чтобы узнать, не было ли ошибки при EXEC.

    8. Восстановите DS, ES и локальную DTA, если необходимо.

    9. Проверьте код выхода через функцию 4dH WAIT (если надо).

    Все открытые файлы дублируются, так что ребенок может обрабатывать данные как через описатели файлов, так и через стандартный в/в. режимы доступа описателей дублируются, но любые активные блокировки файлов не будут относиться к ребенку. См. функцию 5cH. после возврата из ребенка, векторы INT 22H Terminate, INT 23H Ctrl-Break и INT 24H Critical Error восстанавливаются в их предыдущие значения.

    AL=3 LOAD: Эта подфункция используется для загрузки «оверлея».

    DS:DX указывает на ASCIIZ имя файла, а ES:BX указывает на «LOAD»-версию блока параметров EXEC. Главное значение этой подфункции в том, что она считывает заголовок EXE и выполняет необходимые перемещения сегментов, как это требуется для программ .EXE.

    Илон Маск рекомендует:  SetLength - Процедура Delphi
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL