ПРОЦЕДУРЫ. ТАБЛИЧНАЯ ТРАНСЛЯЦИЯ. ПЕРЕВОД ДВОИЧНЫХ ДАННЫХ В СИМВОЛЬНУЮ ФОРМУ 



Теоретические сведения

Процедуры. Процедурой в ассемблере называют участок программы, управление которому передается при помощи команды CALL, а выход из которого осуществляется командой RET. Использование процедур преследует две основные цели: во-первых, уменьшение объема программы путем повторного использования ее частей, и, во-вторых, облегчение разработки программы за счет разбиения общей задачи программы на подзадачи и решения каждой из подзадач по отдельности.

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

 

name PROC [near │ far]

   ...               ; тело процедуры

name ENDP

 

Имя (в примере — name) играет роль адреса процедуры (эквивалентно метке первой команды процедуры) и используется при ее вызове. Имя указывается в качестве операнда команды CALL. Эта команда помещает в стек адрес следующей за ней команды (этот адрес содержится в регистре IP и представляет собой адрес возврата), а затем передает управление процедуре по указанному адресу (загружает адрес в IP). Возврат из процедуры, как уже отмечалось, осуществляется командой RET, которая забирает из стека адрес возврата и передает по нему управление (загружает в IP).

 

; Процедура Name

name PROC

   ...               ; тело процедуры

   ret               ; возврат из ближней процедуры

name ENDP

; Основная программа

   ...

   call name     ; вызов ближней процедуры

   ...

 

Процедура может быть описана как до, так и после вызывающей программы и может быть расположена как в том же сегменте (ближняя процедура — описатель near), так и в другом (дальняя процедура — far). В последнем (более редком) случае команда CALL помещает в стек полный адрес возврата (два слова — текущие CS:IP) и загружает в CS:IP полный адрес процедуры, а команда RET считывает из стека двухсловный адрес возврата и помещает в CS:IP. Ассемблер при трансляции использует эти варианты команд CALL и RET в том случае, если процедура и, возможно, ее вызов оформлены с помощью описателя far как дальние. Если же описатель не указан, по умолчанию принимается near.

(В виде процедур часто оформляются участки программы, выполняющие какие-либо служебные, вспомогательные задачи и управление которым передается неоднократно. Главная часть программы, тем не менее, тоже может быть оформлена с помощью директив PROC и ENDP. Однако, так как передача управления главной процедуре будет осуществляться не командой CALL, вместо команды RET необходимо вызвать функцию DOS завершения программы. Имя главной процедуры можно использовать при указании точки входа в директиве конца программы END.)

Перевод чисел в символьную форму 16-ричной системы. При создании самых разнообразных программных продуктов часто требуется выводить на экран какие-либо числа. При этом возникает необходимость преобразования этих чисел из внутреннего двоичного формата, в котором они обрабатываются ЭВМ, в символьный, в котором они могут быть отображены на экране. Для представления чисел используются различные системы счисления. Для человека привычна десятичная система. Однако при выводе содержимого ячеек оперативной памяти, адресов и других системных значений чаще используется 16-ричная система счисления, так как ее использование в этом случае более естественно. Кроме того, преобразование в 16-ричную систему осуществляется проще, чем в десятичную.

Перевод чисел из двоичной системы счисления в 16-ричную осуществляется следующим образом: разряды двоичного числа группируются по 4, начиная с младшего, после чего каждая четверка разрядов (тетрада) преобразуется в соответствующую 16-ричную цифру (в нашем случае — в ASCII-код этой цифры).

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

Для выделения значений отдельных битов двоичного числа применяется операция логического умножения (AND) по маске. Например, для выделения второй по старшинству тетрады двоичного слова (предположим, регистра АХ) используется маска 0F0h, например:

 

AND
AND
      1010 1011 1100 1101b = ABCDh (исходное число в АХ)

      0000 0000 1111 0000b = 00F0h (маска)

      0000 0000 1100 0000b = 00С0h (результат);

 

соответствующая ассемблерная команда:

 

      and ax, 0F0h

 

Для сдвига совокупности битов относительно разрядной сетки используются команды логического сдвига (в частности, SHR — сдвиг вправо). Чтобы сдвинуть цифру С, полученную выше, можно использовать команду

 

      shr ax, 4    ; сдвиг вправо на 4 разряда

 

После того, как тетрада подготовлена, необходимо преобразовать ее в ASCII‑код. Одним из методов является использование таблицы преобразования, содержащей ASCII-коды преобразуемых цифр. При этом номер ячейки таблицы, соответствующий одной цифре, заменяется значением данной ячейки — кодом цифры. Таблица преобразования (трансляции) оформляется в виде набора символов цифр, записанных в порядке возрастания:

 

tabl  db '0123456789ABCDEF'

 

Для выборки значения из таблицы удобно использовать команду табличной трансляции XLAT (без операндов). Перед выполнением XLAT необходимо занести в регистры DS:BX полный адрес таблицы, а в AL — номер (n) ячейки таблицы. XLAT помещает в тот же регистр AL значение n-й ячейки таблицы, например:

 

      lea bx, tabl

      mov al, 9

      xlat            ; AL = '9' = 39h

 

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

При переводе в символьную форму чисел размером более одного байта, расположенных в памяти, необходимо учитывать их «перевернутое» хранение. Например, следующие друг за другом байты памяти со значениями 7Dh и 0A9h образуют словное число 0A97Dh. То же касается числовых форматов с размером разрядной сетки, не кратным восьми. Например, при использовании 12-битных (полуторабайтовых форматов) три следующих друг за другом байта со значениями 7Dh, 0A9h и 5Fh образуют два 12-битных числа 0A7Dh (младшее) и 5F9h (старшее)

Задание

1. Написать процедуру перевода 16-битового (2-байтового) числа в ASCII-формат в 16-ричной системе счисления, используя команду XLAT. Организовать в процедуре перевода циклический перевод двоичных тетрад, начиная со старшей.

Определить в области данных программы строку с фамилией, например:

 

surname db 'Иванов' ;моя фамилия

 

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

   Ив | 88A2h

   ан | A0ADh

   ов | AEA2h

 

2. Написать процедуру перевода 32-битового (4-байтового) числа в ASCII-формат в 16-ричной системе счисления, используя команду XLAT. Написать, кроме того, процедуру вывода на экран содержимого области памяти (дампа) в виде 16-ричных чисел. Вход процедуры: DS:DX — адрес области памяти; CX — длина в байтах.

3. Написать процедуру перевода 16-битового (2-байтового) числа в ASCII-формат в 8-ричной системе счисления, используя команду XLAT. С помощью этой процедуры вывести на экран числовое представление своей фамилии (пояснения см. в задании 1).

4. Написать процедуру перевода 8-битового (байтового) числа в обратном коде в его символьный эквивалент со знаком в 16-ричной системе счисления, используя команду XLAT. Определить в памяти строку, содержащую латинские и русские буквы. Выдать на экран эту строку и ее числовой знаковый эквивалент, например:

 

Пакет TASM

­–70 –5F –55 –5A –1D +20 +54 +41 +53 +4D

 

5. Написать процедуру перевода 64-битового (8-байтового) числа в ASCII-формат в 16-ричной системе счисления, используя команду XLAT. Организовать в процедуре перевода циклический перевод двоичных тетрад, начиная с младшей. Ввести с клавиатуры строку символов (Enter — конец ввода) и вывести на экран ее числовое представление.

6. Написать процедуру перевода 32-битового (4-байтового) числа в ASCII-формат в 8-ричной системе счисления, используя команду XLAT. Организовать в процедуре перевода циклический перевод двоичных триад, начиная с младшей. Вывести с помощью этой процедуры на экран числовое представление участка памяти по адресу ES:0000h длиной 256 байт.

7. Написать с использованием команды XLAT процедуру приведения строчных русских букв в символьной строке к верхнему регистру (малые → большие), а также процедуру перевода 4-битового (полубайтового) числа в ASCII-формат в 16-ричной системе счисления. В программе организовать ввод преобразуемых строк с клавиатуры и их порядковую нумерацию в 16-ричной системе счисления при выводе на экран; выход — Esc.

8. Написать процедуру перевода 16-битового числа в ASCII-формат в 32-ричной системе счисления, используя команду XLAT. В программе организовать три сегмента; вывести на экран с помощью написанной процедуры адреса сегментов программы.

9. Написать с использованием команды XLAT процедуру преобразования символьной строки из кодировки DOS в кодировку Win, а также процедуру перевода 8-битового числа в ASCII-формат в 8-ричной системе счисления. В программе организовать ввод преобразуемых строк с клавиатуры и их порядковую нумерацию в 8-ричной системе счисления при выводе на экран; выход — Esc.

10. Написать процедуру перевода 16-ричной ASCII-цифры в ее двоичный эквивалент (4 бита) с помощью команды XLAT. В программе организовать ввод преобразуемых цифр с клавиатуры и вывод на экран символов с кодами, равными полученному числовому результату.

11. Написать с использованием команды XLAT процедуру преобразования символьной строки, в результате которого латинские символы были бы заменены символами с кодами, равными скан-кодам соответствующих клавиш. В программе организовать ввод преобразуемых строк с клавиатуры; выход — по клавише Alt-X.

12. Написать с использованием команды XLAT процедуру преобразования 12-битового (полуторабайтового) числа в ASCII-формат в 16-ричной системе счисления. С помощью этой процедуры вывести на экран числовое представление своей фамилии.

13. Написать с использованием команды XLAT процедуру преобразования символьной строки, в результате которого латинские символы были бы заменены соответствующими тем же клавишам кириллическими символами (например, 'ghbdtn' → 'привет').

14. Написать с использованием команды XLAT процедуру преобразования дробного числа в символьную форму 16-ричной системе счисления. Исходный формат хранения числа — 2-байтовый с фиксированной точкой, по 8 бит для целой и дробной части. С помощью этой процедуры вывести на экран числовое представление своей фамилии.

 

Лабораторная работа №7

РАБОТА С ФАЙЛАМИ

Теоретические сведения

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

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

Имя файла (и, соответственно, каталога) может содержать от 1 до 8 символов непосредственно в имени и от 0 до 3 символов — в расширении файла, обычно поясняющем его тип. Имя и расширение отделяются точкой. Суммарная длина имени, таким образом, составляет максимум 12 байт.

DOS поддерживает ряд следующих функций для работы с файлами:

 

№ в AH Описание Вход Выход
3Сh/5Bh Создать файл/ новый файл DS:DX ® ASCIIZ; CX = атрибуты AX = дескриптор
3Dh Открыть файл DS:DX ® ASCIIZ; AL = код доступа (0 - чтение, 1 - запись, 2 - чтение/запись) AX = дескриптор
3Eh Закрыть файл BX = дескриптор  
3Fh Читать из файла BX = дескриптор; CX = число байт; DS:DX ® буфер-приемник AX = число считанных байт
40h Писать в файл BX = дескриптор; CX = число байт; DS:DX ® буфер-источник AX = число записанных байт
42h Установить указатель BX = дескриптор; CX:DX = сдвиг в байтах AL = код метода (сдвиг относи-тельно: 0 - начала файла; 1 – те­кущего положения; 2 - конца файла) DX:AX = текущее положение указателя относительно начала файла
43h Получить/уста-новить атрибут DS:DX ® ASCIIZ; AL = 0 - получить, 1 - установить; CX = новый атрибут (при AL = 1) CX = текущий атрибут (при AL = 0)
57h Получить/уста-новить дату и время создания AL = 0 - получить, 1 - установить; BX = дескриптор; CX = новое вре­мя, DX = новая дата (при AL = 1) CX = время, DX = дата (при AL = 0)
39h Создать каталог DS:DX ® ASCIIZ  
3Ah Удалить каталог DS:DX ® ASCIIZ  
41h Удалить файл DS:DX ® ASCIIZ  
47h Получить полное имя текущего каталога DS:SI ® буфер для имени (до 64 б); Dl = номер диска (0 = текущий, 1 = A, и т. д.) полное имя в буфере в формате ASCIIZ
4Eh Найти первый файл DS:DX ® ASCIIZ (имя/маска); CX = атрибуты

[DTA+21] - атрибут;

[DTA+22] - дата;

[DTA+24] - время;

[DTA+26] - размер;

[DTA+30] - ASCIIZ-имя

или CF = 1 (не найден)

4Fh Найти следующий файл Данные в DTA после предыдущего поиска
56h Переименовать файл DS:DX ® ASCIIZ - старое имя; ES:DI ® ASCIIZ - новое имя  
5Ah Создать уникальный файл DS:DX ® ASCIIZ - диск и путь\; CX = атрибуты AX = дескриптор; DS:DX ® ASCIIZ - полное имя

 

ASCIIZ – '(путь\)имя',0 (если путь не указан, используется текущий каталог).

Все функции в случае ошибки устанавливают CF и возвращают в AX код ошибки:

 

Hex   Dec Значение Hex   Dec Значение
1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 Неверный номер функции Файл не найден Путь не найден Слишком много открытых файлов Доступ не разрешен Неверный дескриптор Разрушены блоки упр. памятью Недостаточно памяти Неверный адрес блока памяти 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h 11h 12h 10 11 12 13 14 15 16 17 18 Неверное окружение Неверный формат Неверный код доступа Неверная дата  (не используется) Задан неверный диск Нельзя удалять тек. каталог Не то устройство Больше нет искомых файлов

 

Стандартные дескрипторы:

 

0 CON - стандартный ввод (клавиатура);

1 CON - стандартный вывод (экран); 

2 стандартное устройство ошибок (экран);

3 AUX - асинхронный адаптер (COM1);

4  стандартный принтер (LPT1).

 

Атрибуты (биты):

 

  a d s v h r

a - (archive) архивный;

d - (directory) каталог;

v - (volume) метка тома;

s - (system) системный;

h - (hidden) скрытый;

r - (read only) только для чтения.

 

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

Начиная с версии 2 в MS-DOS используется дескрипторный метод работы с файлами. При создании или открытии файлу присваивается 16-разрядный двоичный номер, называемый дескриптором (или описателем). В дальнейшем при выполнении операций чтения, записи и других необходимо указывать присвоенный файлу дескриптор.

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

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

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

Поиск группы файлов, имена которых удовлетворяют определенному шаблону, выполняется в два этапа. На первом этапе используется функция ’Найти первый файл’, при этом указывается шаблон, который может содержать путь к обрабатываемому каталогу и шаблонные символы ’*’ (последовательность допустимых символов произвольной длины) и ’?’ (любой допустимый символ в данной позиции). Если путь не указан, подразумевается текущий каталог (это справедливо и в других подобных случаях). Если файл не найден, устанавливается флаг CF, иначе информация о найденном файле записывается в область DTA. На втором этапе вызывается функция ’Найти следующий файл’, которая использует информацию из DTA после предыдущего поиска. Эта функция при каждом новом вызове находит следующий файл, удовлетворяющий первоначальному шаблону. Файлы находятся в порядке их следования в записи каталога. Подкаталоги не обрабатываются.

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

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

 

; Данные

fname db '1.txt', 0 ; ASCIIZ-имя файла

string db 'Данные' ; записываемая строка

len   = $-string ; длина строки

ermes db 'Ошибка создания файла!'

 

; Код

      assume cs:cod, ds:dat

b:    mov ax, dat

      mov ds, ax   ; инициализация DS адресом сегмента данных

; Создадим файл

      mov ah, 3Ch  ; функция ’Создать файл’

      lea dx, fname ; DS:DX -> ASCIIZ-имя

      xor cx, cx   ; без атрибутов

      int 21h

      jc er       ; если ошибка – на обработку

; Запишем в файл строку

      mov bx, ax   ; сохраним дескриптор созданного файла

      mov ah, 40h  ; функция записи в файл или на устройство

      lea dx, string ; DS:DX -> записываемая строка

      mov cx, len

      int 21h

; Закроем файл (в BX - дескриптор)

      mov ah, 3Eh

      int 21h

exit: mov ax, 4C00h

      int 21h

; Обработка ошибки создания файла

er:

      ...             ; вывод сообщения ermes

      jmp exit

 

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

Задание

1. В конец всех файлов с расширением ASM в текущем каталоге дописать строку «Обработан». Создать новый файл PROCESS.NUM и записать в него число (в 16-ричной системе) обработанных файлов.

2. Определить глубину вложенности ветви каталогов, произрастающей из текущего каталога. Создать новый файл DEEPTREE.NUM и записать в него число (в 16-ричной системе), соответствующее найденной глубине.

3. Конкатенация файлов. Содержимое всех файлов с расширением ASM в текущем каталоге «слить» (скопировать) в один файл MYASM.TXT.

4. Поиск строки в файле. Задать в исходном тексте программы имя некоторого текстового файла и строку. Определить, имеется ли в файле указанная строка. Создать новый файл FINDSTR.REP и записать в него отчет о результатах поиска.

5. Копирование файла. Задать в исходном тексте программы имя некоторого тестового файла, размер которого может превышать 64 Кб, и имя нового файла-копии. Создать второй файл и скопировать в него содержимое первого.

6. Определить совокупный размер всех файлов с расширением ASM в текущем каталоге. Создать новый файл ASMSIZE.TXT и записать в него найденное число (в 16-ричной системе).

7. Разделение файла на фрагменты. Задать в исходном тексте программы имя некоторого тестового файла и размер фрагмента. Создать в текущем каталоге файлы указанного размера с именами F001.FRG, F002.FRG, …, F00A.FRG, …, содержащие фрагменты исходного файла.

8. У всех файлов с расширением ASM в текущем каталоге сбросить атрибут «архивный» и установить атрибут «только чтение». Список обработанных файлов поместить в новый файл REPORT.TXT.

9. Поиск символа в файле. Запросить с клавиатуры имя файла и искомый символ. Определить, сколько раз встречается символ в файле. Создать новый файл FINDSYMB.REP и записать в него найденное число в 8-ричной системе счисления.

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

11. Запросить с клавиатуры маску поиска. Осуществить поиск файлов по указанной маске в текущем каталоге. Создать подкаталог FINDMASK, в нем файл REPORT.FND и записать в него отчет о поиске, включающий маску, имя текущего каталога (в котором осуществлялся поиск) и список имен найденных файлов.

12. Задать в исходном тексте программы имя некоторого файла с исходным текстом программы на ассемблере. В указанном файле подсчитать объем комментариев в байтах и в процентах относительно общего размера файла. Результаты записать в виде 16-ричных чисел в конец этого же файла.

13. Все файлы с расширением ASM в текущем каталоге сделать младше на 10 минут.

14. Добавить в конец имени каждого файла с расширением ASM в текущем каталоге символ подчеркивания (например, LAB1.ASM переименовать в LAB1_.ASM). Если имя файла содержит 8 символов, заменить последний символ символом подчеркивания.

 


Предисловие..........................................................................................................................

Введение.................................................................................................................................

Лабораторная работа №1. Структура EXE-программы на ассемблере. Подготовка к выполнению

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

Лабораторная работа №2. Использование сервисных подпрограмм. Циклы. Формирование и вывод на экран строки ASCII-символов..............................................................................................

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

Лабораторная работа №3. Управление курсором при выводе. Вложенные циклы. Формирование и вывод на экран таблицы символов ASCII..........................................................................

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

Лабораторная работа №4. Посимвольный ввод с клавиатуры. Анализ нажатия функциональных клавиш и комбинаций...........................................................................................................

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

Лабораторная работа №5. Ввод с клавиатуры и обработка символьных строк (пароль)........

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

Лабораторная работа №6. Процедуры. Табличная трансляция. Перевод двоичных данных в символьную форму.................................................................................................................

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

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

Теоретические сведения..............................................................................................

Задание..........................................................................................................................

 


 


Дата добавления: 2018-04-05; просмотров: 643; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!