Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Архитектура процессора Intel 8086.
Лабораторная работа №1
Архитектура процессора Intel 8086. Цель. Изучение структуры процессора Intel 8086, и основ его программирования. Задание. Используя представленный теоретический материал, имеющуюся литературу и предоставленное преподавателем обучающее программное обеспечение студент должен изучить структуру микропроцессора Inlet 8086. В результате выполнения практической работы студент должен знать: - структуру микропроцессора Intel 8086; - назначение входящих в него блоков и устройств; - регистры микропроцессора и их основное назначение; - структуру и назначение регистра флагов; - структуру памяти и особенности принципа сегментации; - принцип прерываний; - режимы адресации; - последовательность написания программ на языке Ассемблера; - назначение программ, входящих в пакет Turbo Assembler. Структура EXE- и COM- программы. Вывод на экран Цель. Изучение структуры EXE- и COM-программы. Получение навыков вывода данных на экран монитора. Задание. Разработать EXE-программу вывода символа на экран, и COM- программу вывода на экран строки. Теоретические сведения Структура программы Исходный программный модуль состоит из команд и директив. Команды управляют работой процессора, а директивы указывают ассемблеру и редактору связей каким образом следует объединять, команды для создания модуля, который и станет работающей программой. Команда на языке ассемблера состоит не более чем из четырех полей. Ниже приведен формат и пример команды с указанием названия его полей: Метка Код операции Операнды; Комментарий MET: MOVE AX, BX; Пересылка
Единственное обязательное поле – поле кода операции, определяющее команду, которую должен выполнить микропроцессор. Поле операндов определяется кодом операции и содержит дополнительную информацию о команде. Метка содержит в символическом виде адрес команды, что необходимо для организации переходов (ссылок). Поле комментария служит для удобства программиста и компилятором игнорируется. Оператор директивы состоит из символического имени, кода псевдооперации, поля операндов и комментария. Структура директивы аналогична структуре команды. Второе поле – код псевдооперации определяет смысловое содержание директивы. Как и команды, у директивы есть операнды, причем их может быть один или несколько и они отделяются друг от друга запятыми. Допустимое число операндов в директиве определяется кодом псевдооперации. Например: DB 0, 0, 0, 0, 0 END START
Директива может быть помечена символическим именем и содержать поле комментария. Символическое имя, стоящее в начале директивы распределения памяти, называется переменной. В отличие от метки команды после символического имени директивы двоеточие не ставиться. Программа на языке ассемблера состоит из программных модулей, содержащихся в различных файлах. Каждый модуль, в свою очередь, состоит из операндов или директив ассемблера и заканчивается директивой END. Метка, стоящая после кода псевдооперации END, является точкой входа в программу. Каждый модуль разбивается на отдельные части директивами сегментации, определяющими начало и конец сегмента. Любой сегмент начинается директивой начала сегмента – SEGMENT и заканчивается директивой конца сегмента – ENDS. В начале директив сегментации ставится имя сегмента. Каждый сегмент может быть также разбит на части. В общем случае информационные сегменты SS, ES и DS состоят из определений данных, а программный сегмент CS – из команд и директив, группирующих команды в блоки. Программный сегмент может разбиваться на части директивами определения процедур – некоторых выделенных блоков программы. Как и для определения сегмента, имеются две такие директивы – директива начала PROC и директива конца ENDP. Процедура имеет имя, которое должно включаться в обе директивы, процедуры в сегменте могут располагаться последовательно одна за другой, могут быть также вложенными одна в другую. Принципиальной особенностью COM-программы является то, что в отличие от EXE-программы, которая содержит отдельные сегменты данных, стека и кода, COM-программ, в большинстве случаев, может содержать лишь один основной сегмент (сегмент кода), в котором размещаются и код, и данные, и стек. Кроме того, EXE-программа, в отличие от COM-программы, содержит так называемый EXE-заголовок (256 байт), при помощи которого загрузчик выполняет настройку ссылок на сегменты в загруженном модуле, а так как и COM- и EXE- программа должна загружаться с адреса PSP: 0100h (100h=256), COM-программа должна содержать в начале сегмента кода директиву, позволяющую осуществить такую загрузку (ORG 100H). Ниже приведены примеры, иллюстрирующие основные особенности структуры EXE- и COM-программ, написанных на языке ассемблера: Пример. Структура EXE-программы: ; Определение сегмента стека STAK SEGMENT STACK DB 256 DUP (? ) STAK ENDS ; Определение сегмента данных DATA SEGMENT SYMB DB '#'; Описание переменной с именем SYMB ; типа Byte и со значением «#» ...; Определение других переменных DATA ENDS ; Определение сегмента кода CODE SEGMENT ASSUME CS: CODE, DS: DATA, SS: STAK ; Определение подпрограммы PROC1 PROC ...; Текст подпрограммы PROC1 ENDP START: XOR AX, AX; Точка входа в программу START MOV BX, data; и обязательная инициализация MOV DS, BX; регистра DS в начале программы CALL PROC1; Пример вызова подпрограммы ...; Текст программы MOV AH, 4CH; Операторы завершения программы INT 21H CODE ENDS END START
Пример. Структура COM-программы: ; Определение сегмента кода CODE SEGMENT ASSUME CS: CODE, DS: CODE, SS: CODE ORG 100H; Начало необходимое для COM-программы START: ...; Текст программы MOV AH, 4CH INT 21H; Операторы завершения программы ; ===== Data ===== BUF DB 6; Определение переменной типа Byte ...; Определение других переменных CODE ENDS END START
Вывод на экран Вывод информации в ассемблерных программах осуществляется обычно при помощи сервисных функций DOS (прерывание 21h) или BIOS (прерывание 10h). Процесс вывода состоит в следующем: - определенные регистры микропроцессора загружаются выводимой информацией или адресом буфера, содержащего выводимую информацию; - в регистр AH заносится номер используемой для операции вывода функции; - инициируется прерывание. Ниже представлен перечень функций прерывания 21h и 10h, использующихся для вывода информации. Прерывание 21h. Функция 02h Вывод на дисплей. Вход. AH=02h DL=выводимый символ Выход. Нет
Описание. Посылает символ из DL на стандартный вывод. Обрабатывает символ Backspace (ASCII 8), перемещая курсор влево на одну позицию и оставляя его в новой позиции. Функция 05h Вывод на принтер. Вход. AH=05h DL= символ, записываемый на стандартный принтер Выход. Нет
Описание. Посылает символ в DL на стандартное устройство принтера, обычно LPT1. Команда DOS MODE может перенаправить этот вывод в последовательный порт.
Функция 09h Выдать строку. Вход. AH=09h DS: DX=адрес строки, заканчивающейся символом '$'. Выход. Нет
Описание. Строка, исключая завершающий ее символ '$', посылается на стандартный вывод. Символы Backspace обрабатываются как в функции 02h. Обычно, чтобы перейти на новую строку, включают в текст пару CR/LF (ASCII 13H и ASCII 0aH). Строки, содержащие '$', можно выдать через 40h (BX=0), которая посылает символ в DL на стандартное устройство принтера, обычно LPT1.
Прерывание 10h. Функция 02h Вход. AH=02h BH = видео страница DH, DL = строка, колонка (считая от 0) Выход. Нет
Описание. Устанавливает курсор в позицию DH, DL. Установка курсора на строку 25 делает курсор невидимым. Функция 09h Писать символ/атрибут в текущей позиции курсора. Вход. AH=09h BH = номер видео страницы AL = записываемый символ CX = счетчик (сколько экземпляров символа записать) BL = видео атрибут (текст) или цвет (графика) Выход. Нет
Описание. Выводит на экран в текущую позицию курсора символ с заданным атрибутом.
Функция 0ah Писать символ в текущей позиции курсора. Вход. AH=0ah BH = номер видео страницы AL = записываемый символ CX = счетчик (сколько экземпляров символа записать) Выход. Нет
Описание. Выводит на экран в текущую позицию курсора заданный символ.
Функция 13h Вывод строки. Вход. AH=13h ES: BP – выводимая строка CX = длина строки (подсчитываются только символы) DH, DL = позиция (строка, колонка) начала вывода BH = номер страницы AL = код подфункции: 0=атрибут в BL; курсор без изменения 1=атрибут в BL; курсор – в конец строки 2=формат строки: char, attr,...; курсор без изменения 3=формат строки: char, attr,...; курсор – в конец строки Выход. Нет
Описание. Выдает строку в позиции курсора. Символы 0dH (CarRet), 0aH (LineFeed), 08H (backspace) и 07H (Beep) трактуются как команды управления и не высвечиваются.
Некоторые функции прерывания 10h используют для вывода атрибут символа. Для адаптеров цветной графики в текстовом режиме атрибут определен следующим образом:
foreground – цвет переднего плана (от 0 до 0fH); brt – интенсивность: 1=передний план яркий; background – фоновый цвет (от 0 до 7); fgB – мерцание: 1=передний план мерцает; Видеоадаптер поддерживает следующие цвета:
Вычислить значение атрибута можно, используя следующее выражение: (фон * 16) + передний план + (128 для мерцания)
Приведенный ниже фрагмент программы иллюстрирует процесс вывода строки на экран. MOV AH, 09H; Выбор функции прерывания MOV DX, OFFSET STR; Занесение в DX адреса выводимой строки INT 21H ... STR DB 10, 13, 'Hello$' ; Описание строки
Лабораторная работа №2 Циклы. Ввод с клавиатуры Цель. Получение навыков организации циклических структур в ассемблерных программах. Ввод символов с клавиатуры. Задание. Разработать программу, ввода строковых данных с клавиатуры. Произвести обработку введенных строк в соответствии с вариантом и вывести результат на экран. Таблица. Варианты заданий
Теоретические сведения Ввод с клавиатуры Процесс ввода информации в ассемблерных программах осуществляется аналогично выводу: - в регистр AH заносится номер функции ввода; - инициируется прерывание, после выполнения которого определенные регистры процессора содержат либо введенную информацию, либо адрес буфера с введенной информацией. Ниже описан ряд функций прерывания 21h, используемых для ввода информации с клавиатуры. Функция 01h Ввод с клавиатуры. Вход. AH=02h Выход. AL= символ, полученный с клавиатуры
Описание. Считывает (ожидает) символ со стандартного входного устройства. Отображает этот символ на стандартное выходное устройство (эхо). Ввод расширенных клавиш ASCII (F1-F12, PgUp, курсор и т.п.) требует двух обращений к этой функции. Первый вызов возвращает AL=0. Второй вызов возвращает в AL расширенный код ASCII.
Функция 07h Нефильтруемый консольный ввод без эха. Вход. AH=07h Выход. AL= символ, полученный с клавиатуры
Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. Не фильтрует. Не проверяет на Ctrl-Break, backspace и т.п. Необходимо вызывать дважды для ввода расширенного символа ASCII.
Функция 08h Консольный ввод без эха. Вход. AH=08h Выход. AL= символ, полученный с клавиатуры
Описание. Считывает (ожидает) символ со стандартного входного устройства и возвращает этот символ в AL. При обнаружении Ctrl-Break выполняется прерывание INT 23H. Необходимо вызывать дважды для ввода расширенного символа ASCII.
Функция 0ah Буферизированный ввод строки. Вход. AH=0ah DS: DX=адрес входного буфера (смотри ниже) Выход. Буфер содержит ввод, заканчивающийся символом CR (ASCII 0dH)
Описание. При входе буфер по адресу DS: DX должен быть оформлен следующим образом:
MAX - максимально допустимая длина ввода (от 1 до 254) При выходе буфер заполнен данными следующим образом:
LEN - действительная длина данных без завершающего CR (здесь – 0dH). Символы считываются со стандартного ввода вплоть до CR (ASCII 0dH) или до достижения длины MAX-1. Если достигнут MAX-1, включается консольный звонок для каждого очередного символа, пока не будет введен возврат каретки CR (нажатие Enter). Второй байт буфера заполняется действительной длиной введенной строки, не считая завершающего CR. Последний символ в буфере – всегда CR (который не засчитан в байте длины). Символы в буфере (включая LEN) в момент вызова используются как «шаблон». В процессе ввода действительны обычные клавиши редактирования: Esc выдает " \" и начинает с начала, F3 выдает буфер до конца шаблона, F5 выдает " @" и сохраняет текущую строку как шаблон, и так далее. Большинство расширенных кодов ASCII игнорируются. При распознавании Ctrl-Break выполняется прерывание INT 23H (буфер остается неизменным).
Функция 0ch Ввод с очисткой Вход. AH=0ch AL= номер функции ввода (01H, 06H, 07H, 08H или 0aH) Выход. Нет
Описание. Очищает буфер опережающего ввода стандартного ввода, а затем вызывает функцию ввода, указанную в AL. Это заставляет систему ожидать ввод очередного символа. Следующие значения допустимы в AL: 01H – ввод с клавиатуры; 06H – ввод с консоли; 07H – нефильтрующий без эха; 08H – ввод без эха; 0aH – буферизованный ввод.
Приведенный ниже фрагмент программы иллюстрирует буферизированный ввод строки: MOV AH, 0AH; занесение в AH номера функции LEA DX, BUF; загрузка DX адресом буфера BUF INT 21H ... BUF DB 30, 00, 30 DUP ('$'), ’$’
При организации буфера BUF (размер буфера 30 байт), он весь заполняется символами «$», что удобно, если введенную строку в дальнейшем необходимо выводить на экран или в файл (при условии, конечно, что для ввода буфер будет использоваться лишь однократно). Теоретические сведения Ввод числовой информации Ввод числовой информации в ассемблерную программу обычно осуществляется в два этапа: - ввод строки содержащей число; - перевод строки в число. Ввод строк рассматривался в предыдущих практических работах. Для разработки алгоритма перевода введенной строки в число проанализируем структуру числа в позиционной системе счисления (в такой системе счисления вес цифры определяется ее местоположением в числе): 2398=2*1000+3*100+9*10+8=2*103+3*102+9*101+8*100
Таким образом, для перевода строки в число из введенной строки «2398» необходимо последовательно выделять цифры и производить суммирование произведений этих цифр и множителей соответствующих позиции цифры в числе. Если буфер для ввода строки был организован, например, следующим образом: BUF 05, 00, 05 DUP (? )
то после ввода строки «2398» он будет выглядеть (в шестнадцатеричной системе счисления) так: 05, 04, 32, 33, 39, 38, 0d
где первый байт – размер буфера, второй – количество введенных символов (без завершающего символа CR), третий, четвертый, пятый, шестой и седьмой – коды символов «2», «3», «9», «8» и «CR» соответственно. Легко заметить, что для того, чтобы из кода цифры получить саму цифру необходимо из соответствующего кода вычесть 30h (шестнадцатеричный код нуля). Затем, последовательно в цикле (второй байт – количество введенных символов) выбирая цифры, формировать соответствующий множитель, вычислять произведение и производить суммирование. Нижеследующий фрагмент программы иллюстрирует описанный алгоритм (символы рассматриваются справа налево). ; Ввод числа в виде строки MOV AH, 0AH; в AH номер функции LEA DX, BUF; DS: DX адрес буфера для ввода INT 21H ; Перевод строки в число, результат в DI MOV DI, 0 LEA BX, BUF+1; в BX адрес второго элемента буфера MOV CX, [BX]; в CX количество введенных символов XOR CH, CH MOV SI, 1; в SI множитель MET: PUSH SI; сохраняем SI (множитель) в стеке MOV SI, CX; в SI помещаем номер текущего символа MOV AX, [BX+SI]; в AX помещаем текущий символ XOR AH, AH POP SI; извлекаем множитель (SI)из стека SUB AX, 30H; получаем из символа (AX) цифру MUL SI; умножаем цифру (AX)на множитель (SI) ADD DI, AX; складываем с результирующим числом MOV AX, SI; помещаем множитель (SI) в AX MOV DX, 10 MUL DX; увеличиваем множитель (AX) в 10 раз MOV SI, AX; перемещаем множитель (AX) назад в SI LOOP MET; переходим к предыдущему символу Лабораторная работа №3 Теоретические сведения Подпрограммы Как уже было сказано выше, программный сегмент может разбиваться на части директивами определения подпрограмм (процедур). Для определения процедур используются две директивы – директива начала PROC и директива конца ENDP. Процедура должна иметь имя, которое включается в обе директивы. В сегменте кода процедуры могут располагаться последовательно, а могут быть вложенными одна в другую. Определение подпрограмм имеет следующий синтаксис: имя_процедуры PROC параметр тело_процедуры имя_процедуры ENDP
Передавать фактические параметры процедуре можно несколькими способами. Простейший способ – передача параметров через регистры: основная программа записывает параметры в какие-либо регистры, а процедура по мере необходимости извлекает их из этих регистров и использует в своей работе. Такой способ имеет один основной недостаток: передавать параметры через регистры можно если их немного (если много, то просто не хватит регистров). Решить это проблему можно, передавая параметры через стек. В этом случае основная программа записывает параметры в стек и вызывает подпрограмму, подпрограмма работает с параметрами и, возвращая управление, очищает стек. Существует несколько разновидностей команды вызова процедуры CALL. Все команды вызова безусловны и используются для передачи управления процедуре. Внутрисегментный вызов NEAR CALL используется для передачи управления процедуре, находящейся в том же сегменте. Межсегментный вызов FAR CALL используется для передачи управления процедуре, находящейся в другом сегменте или даже программном модуле. Командам CALL соответствуют команды возврата RET. Все возвраты – косвенные переходы, поскольку извлекают адрес перехода из вершины стека. Внутрисегментный возврат извлекает из стека одно слово и помещает его в регистр IP, а межсегментный возврат извлекает из стека два слова, помещая слова из меньшего адреса в регистр IP, а слово из большего адреса – в регистр CS. Оператор RET может иметь операнд, который представляет собой значение, прибавляемое микропроцессором к содержимому указателя стека SP после извлечения адреса возврата. Ниже приведен пример программы, в которой передача параметров в подпрограмму выполняется через стек. CODE SEGMENT ... PROC1 PROC MOV BP, SP; загрузка в BP текущего адреса стека MOV BX, [BP+4]; выборка из стека 1 параметра (ca) ... MOV BX, [BP+2]; выборка из стека 2 параметра (ll) ... RET 4; Возврат с удалением 4 слов из стека PROC1 ENDP START: ... MOV AX, ’ca’; Загрузка в AX символов MOV CX, ’ll’; Загрузка в CX символов PUSH AX; Сохранение AX в стек PUSH CX; Сохранение CX в стек CALL PROC1 ... CODE ENDS
Работа с файлами Используется два метода доступа к файлам: метод управляющего блока файла (FCB) и метод дескриптора файла. С помощью метода FCB можно получить доступ только к файлам, находящимся в текущем каталоге. Метод дескриптора файла позволяет получить доступ к любому файлу, независимо от того, какой каталог является текущим. Начиная с DOS версии 2.0, в набор функций прерывания 21h включены UNIX-подобные файловые функции. Идея их состоит в том, что, когда программа открывает файл, DOS возвращает 16-битовое значение «описателя файла» (дескриптора файла) (handle). После этого, когда программа читает, позиционирует, пишет или закрывает файл, она ссылаетесь на него через описатель. Одно из самых больших удобств – то, что можно обращаться к некоторым устройствам так, как будто это дисковые файлы, через зарезервированные описатели DOS: Таблица.Предопределенные описатели DOS
Ниже приведен перечень наиболее часто используемых функций прерывания 21h для работы с файлами через описатели. Функция 3cH Создать файл. Вход. AH=3ch DS: DX=адрес строки ASCIIZ с именем файла CX=атрибут файла Выход. AX=код ошибки, если CF установлен и описатель файла, если ошибки нет.
Описание. Файл создается в указанном (или умалчиваемом) оглавлении и открывается в режиме доступа «чтение/запись». Если файл уже существует, то при открытии файл усекается до нулевой длины. Если атрибут файла – «только чтение», открытие отвергается (атрибут можно изменить функцией 43H).
Функция 5bH Создать новый файл (не должен существовать). Вход. AH=5bh DS: DX=адрес строки ASCIIZ с именем файла CX=атрибут файла Выход. AX=код ошибки, если CF установлен и описатель файла, если ошибки нет
Описание. Этот вызов идентичен функции 3ch, с тем исключением, что он вернет ошибку, если файл с заданным именем уже существует.
Функция 5aH Создать уникальный файл. Вход. AH=5ah DS: DX=адрес строки ASCIIZ с путем (заканчивается \) CX=атрибут файла Выход. AX=код ошибки, если CF установлен и описатель файла, если ошибки нет DS: DX (не изменяется) становится полным ASCIIZ-именем нового файла.
Описание. Открывает (создает) файл с уникальным именем в оглавлении, указанном строкой ASCIIZ, на которую указывает DS: DX. Описание пути должно быть готово к присоединению в его конец имени файла. Необходимо обеспечить минимум 12 байт в конце строки. После возврата строка DS: DX будет дополнена именем файла. DOS создает имя файла из шестнадцатеричных цифр, получаемых из текущих даты и времени. Если имя файла уже существует, DOS продолжает создавать новые имена, пока не получит уникальное имя.
Функция 3dH Открыть файл. Вход. AH=3dh DS: DX=адрес строки ASCIIZ с именем файла AL=режим открытия Выход. AX=код ошибки, если CF установлен и описатель файла, если ошибки нет
Описание. В момент открытия файл должен существовать. Файл открывается в выбранном режиме доступа (AL = 0 – для чтения; AL = 1 – для записи; AL = 2 – для чтения и записи) и указатель «чтения/записи» устанавливается в 0.
Функция 3eH Закрыть файл. Вход. AH=3eh BX=описатель файла Выход. AX= код ошибки, если CF установлен
Описание. BX содержит описатель файла (handle), возвращенный при открытии. Файл, представленный этим описателем, закрывается, его буфер сбрасываются, а оглавление обновляется корректными размером, временем и датой.
Функция 41H Удалить файл. Вход. AH=41h DS: DX=адрес строки ASCIIZ с именем файла Выход. AX=код ошибки, если CF установлен
Описание. Имя файла не может содержать обобщенные символы («? » и «*»). Файл удаляется из заданного оглавления заданного диска. Если файл имеет атрибут только чтение, то перед удалением необходимо изменить этот атрибут через функцию 43H.
Функция 42H Установить указатель чтения/записи (можно также узнать размер файла). Вход. AH=42h BX=описатель файла CX: DX=смещение указателя: (CX * 65536) + DX AL=0 переместить к началу файла + CX: DX AL=1 переместить к текущей позиции + CX: DX AL=2 переместить к концу файла - CX: DX Выход. AX=код ошибки, если CF установлен DX: AX=новая позиция указателя файла (если нет ошибки)
Описание. Перемещает логический указатель чтения/записи к нужному адресу, с которого начнется очередная операция чтения или записи. Вызов с AL=2, CX=0, DX=0 возвращает длину файла в DX: AX. DX здесь старшее значащее слово: действительная длина (DX * 65536) + AX.
Функция 3fH Читать из файла/устройства. Вход. AH=3fh BX=описатель файла DS: DX=адрес буфера для чтения данных CX=число считываемых байт Выход. AX=код ошибки, если CF установлен AX=число действительно прочитанных байт
Описание. CX байт данных считываются из файла или устройства с описателем, указанным в BX. Данные читаются с текущей позиции указателя чтения/записи файла и помещаются в буфер вызывающей программы, адресуемый через DS: DX. Всегда необходимо сравнивать возвращаемое значение AX (число прочитанных байт) с CX (запрошенное число байт): - если AX=CX, (и CF сброшен) – чтение было корректным без ошибок; - если AX=0 – достигнут конец файла (EOF); - если AX< CX (но ненулевой), то возможны два варианта: при чтении с устройства – входная строка имеет длину AX байт; при чтении из файла – в процессе чтения достигнут EOF. Функция 40H Писать в файл/устройство. Вход. AH=40h BX=описатель файла DS: DX=адрес буфера, содержащего данные CX=число записываемых байт Выход. AX=код ошибки, если CF установлен AX=число действительно записанных байт
Описание. CX байт данных записывается в файл или на устройство с описателем, заданным в BX. Данные берутся из буфера, адресуемого через DS: DX и записываются, начиная с текущей позиции указателя чтения/записи файла. Необходимо всегда сравнивать возвращаемое значение AX (число записанных байт) с CX (запрошенное число байт для записи): если AX = CX, запись была успешной; если AX < CX, встретилась ошибка (скорее всего, переполнение). Некоторые функции в качестве параметра используют атрибут файла. Атрибут - это один байт битовых флагов, связанный с каждым файлом и находящийся в элементе оглавления для файла. В атрибуте определены следующие биты:
R- только чтение (нельзя обновлять или удалять); H- скрытый; S- системный; V- метка тома; D- элемент подоглавления; A- архивный; x- не используются.
ASCIIZ строка, содержащая имя файла, имеет вид: «‘d: \путь\имя_файла’, 0»
Если диск и/или путь опущены, они принимаются по умолчанию. После вызова функции описатель файла должен быть сохранен для последующих операций. Количество описателей в системе регламентируется файлом CONFIG.SYS. Приведенный ниже пример иллюстрирует процесс работы с файлом через описатели в ассемблерной программе. ; Создание файла MOV AH, 3CH MOV CX, 0 LEA DX, BUF; DS: DX – адрес ASCIIZ строки с именем INT 21H JC NO_CREATE; Проверка флага переноса ...; Работа с файлом NO_CREATE: ... BUF DB ‘d: \Users\1.txt’, 0
Теоретические сведения Структура DTA Как было сказано ранее, используются два метода доступа к файлу: метод управляющего блока файла (FCB) и метод дескриптора файла. В любом случае программа при работе с файлами должна указывать место в памяти, куда будут помещаться принимаемые данные или откуда будут извлекаться выводимые. Обычно временный буфер устанавливается размером в одну запись и бывает удобно описать его как строковую переменную в сегменте данных. Буфер, используемый методом FCB доступа к файлам, называется областью обмена с диском или DTA. На этот буфер указывает условный указатель, который хранится операционной системой и который может быть изменен программой. В документации этот указатель на DTA часто сам называют DTA. Указатель на DTA устанавливается специальной функцией DOS и после того как он установлен все функции чтения/записи автоматически обращаются к нему. Это означает, что сами функции не должны содержать адрес временного буфера. Для установки указателя на DTA используется функцию 1AH прерывания 21H (DS: DX должны указывать на первый байт DTA). Функция 2FH прерывания 21H сообщает текущую установку указателя DTA (при возврате ES: BX содержат сегмент и смещение DTA). Префикс программного сегмента PSP обеспечивает каждую программу 128-байтным встроенным DTA, начиная со смещения 80H и до 9FH. Программа может использовать его при нехватке памяти. Первоначально указатель на DTA указывает именно на этот буфер, поэтому если программа будет использовать его, то нет нужды устанавливать указатель. Этот буфер по умолчанию особенно удобно использовать с COM файлами, где DS указывает на начало префикса программного сегмента. Для файлов EXE может потребоваться небольшой добавочный код, чтобы использовать DTA по умолчанию.
Таблица. Структура DTA
Формат FileTime:
Примечание: после извлечения года к нему необходимо прибавить 1980. Существует ряд функций для работы с файлами, используя DTA. Наиболее употребимые из них приведены ниже. Функция 1ah Установить адрес DTA. Вход. AH=1aH DS: DX=адрес для DTA Выход. Нет
Описание. Устанавливает адрес DTA.
Функция 2fh Дать текущий DTA. Вход. AH=2fH Выход. ES: BX=адрес для DTA
Описание. Возвращает адрес начала области ввода-вывода (DTA). Поскольку DTA глобальна для всех процессов, в рекурсивной процедуре (например, при проходе по дереву оглавления) может потребоваться сохранить адрес DTA, а впоследствии восстановить его посредством функции 1aH.
Функция 4eh Найти 1-й совпадающий файл. Вход. AH=4eH DS: DX=адрес строки ASCIIZ с именем файла CX=атрибут файла для сравнения Выход. AX=код ошибки, если CF установлен DTA=заполнена данными (если не было ошибки)
Описание. DS: DX указывает на строку ASCIIZ в форме: " d: \путь\имяфайла", 0. Если диск и/или путь опущены, они подразумеваются по умолчанию. Обобщенные символы * и? допускаются в имени файла и расширении. DOS находит имя первого файла в оглавлении, которое совпадает с заданным именем и атрибутом, и помещает найденное имя и другую информацию в DTA.
Функция 4fh Найти следующий совпадающий файл. Вход. AH=4fH DS: DX= адрес данных, возвращенных предыдущей 4eH. Выход. AX=код ошибки, если CF установлен DTA=заполнена данными (если не было ошибки)
Описание. DS: DX указывает на 2bH-байтовый буфер с информацией, возвращенной функцией 4eH (либо DTA, либо буфер, скопированный из DTA).Необходимо использовать эту функцию после вызова 4eH. Следующее имя файла, совпадающее по обобщенному имени и атрибуту файла, копируется в буфер по адресу DS: DX вместе с другой информацией (см. функцию 4eH о структуре файловой информации в буфере, заполняемом DOS). Ниже приведен фрагмент программы, иллюстрирующий организацию поиска файлов в текущем каталоге. ; Установить адрес DTA MOV AH, 01AH LEA DX, FDTA INT 21H ... ; Наити первый совпадающий файл MOV AH, 4EH LEA DX, MASKA MOV CX, 10H INT 21H JC EXIT NEXT: ... ; Найти следующий совпадающий файл MOV AH, 4FH MOV CX, 10H LEA DX, MASKA INT 21H JNC NEXT EXIT: ... ; ========== DTA ========= FDTA DB 15H DUP (? ) FATTR DB? FTIME DW? FDATA DW? FSIZE DD? FNAME DB 0DH DUP ('$') ; ======================== MASKA DB '*.*', 0
Структура PSP Префикс программного сегмента PSP (Program Segment Prefics) – специальная область оперативной памяти размером 256 (100h) байт. PSP может использоваться в программе для определения имен файлов и параметров из командной строки, введенной при запуске программы на выполнение, объема доступной памяти, переменных окружения системы и так далее. После загрузки программы в память сегментные регистры DS и ES указывают на начало PSP этой программы. Таблица. Структура PSP Популярное:
|
Последнее изменение этой страницы: 2016-08-31; Просмотров: 642; Нарушение авторского права страницы