assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 60
Текст из файла (страница 60)
datastr__pech.codedb"Текст для печати"mcv d x , 3 7 8 hlea d i , s t r _ p e c hmov e x , 1 6repoutsbДля организации работы с портами недостаточно знать их номера и назначение. 11е менее важно знать и понимать алгоритмы их работы. Эти сведения можнонайти в документации на устройство (но, к сожалению, далеко не всегда).Реализации более сложных алгоритмов (поиска), основанные на работе с цепочечными командами, приведены в |8].Итоги:• Система команд процессора имеет очень интересную группу команд, позволяющих производить действия над блоками элементов до 64 Кбайт или 4 Гбайтв зависимости от установленной разрядности адреса — use!6 или use32.' : Блоки элементов логически могут представлять собой последовательности элементов с любыми значениями, хранящимися в памяти в виде двоичных кодов.Единственное ограничение состоит в том, что размеры элементов в этих блокахпамяти фиксированы значением 8, 16 пли 32 бита.?•• Команды обработки строк обеспечивают возможность выполнения семи операций-примитивов, обрабатывающих цепочки поэлементно.в- Каждая операция-примитив представлена тремя разными машинными командами и одной псевдокомандой, которая преобразуется транслятором в одну изИтоги2G7трех упомянутых ранее м а ш и н н ы х команд.
Вариан г преобразования определяется типом операндов в команде.Процессор всегда предполагает, что строка-приемник находится и дополнительном сегменте (адресуемом посредством сегментного регистра ES), а строка-источник -- в сегменте д а н н ы х (адресуемом посредством сегментного регистра DS).Процессор адресует строку-]|рпемпик через регистр EDI/DI, а строку-источник —через регистр ESI/SI.Допускается переопределять сегмент для строки-источника, для строки-приемника этого делать нельзя.Особенность работы цепочечных команд состоит в том, что они автоматическивыполняют приращение или уменьшение содержимого регистров EDI/DI и ESI/SI в зависимости от используемо)'! цепочечной команды. Что именно происходит с этими регистрами, определяйся состоянием флага DF, которым управляют команды CLD и 5TD.
Значение, на которое изменяется содержимое индексныхрегистров, определяется типом элементов строки или кодом операции цепочечной команды.Глава 13Сложные структуры данныхПонятие сложного типа данных в ассемблереСредства ассемблера для создания и обработки сложныхструктур данныхМассивыСтруктурыОбъединенияЗаписиВ предыдущих главах при разработке программ мы использовали данные двухтипов.Ж Непосредственные данные, представляющие собой числовые или символьныезначения и являющиеся частью команды.
Непосредственные данные формируются программистом в процессе написания программы для конкретной команды ассемблера.* Данные, описываемые с помощью ограниченного набора директив резервирования памяти, позволяют выполнять самые элементарные операции по размещению и инициализации числовой и символьной информации. При обработкеэтих директив ассемблер сохраняет в своей таблице символов информацию о местоположении данных (значения сегментной составляющей адреса и смещения) и типе данных, то есть единицах памяти, выделяемых для размещения данных в соответствии с директивой резервирования и инициализации данных.Эти два типа данных являются элементарными, или базовыми; работа с нимиподдерживается на уровне системы команд процессора.
Используя данные этихтипов, можно формализовать и запрограммировать практически любую задачу. Нонасколько это будет удобно — вот вопрос.Массивы269Обработка информации в общем случае — процесс очень сложный. Это косвенно подтверждает популярность языков высокого уровня. Одно из несомненных достоинств языков высокого уровня — поддержка развитых структур данных.При их использовании программист освобождается от решения конкретных проблем, связанных с представлением числовых или символьных данных, и получаетвозможность оперировать информацией, структура которой в большей степениотражает особенности предметной области решаемой задачи.
В то же самое время,чем выше уровень такого абстрагирования от конкретного представления данныхв компьютере, тем большая нагрузка должна ложиться на компилятор для создания действительно эффективного кода. Ведь нам уже известно, что в конечномитоге все написанное на языке высокого уровня в компьютере будет представленона уровне машинных команд, работающих только с базовыми типами данных. Таким образом, самая эффективная программа — программа, написанная в машинных кодах, но писать сегодня большую программу в машинных кодах — занятиедовольно бессмысленное.С целью облегчения разработки программ в язык ассемблера на уровне его директив была введена поддержка нескольких сложных типов данных.
Это позволило несколько сгладить различия между языками высокого уровня и ассемблером.У программиста появилась возможность сочетать достоинства языка ассемблераи языков высокого уровня (в направлении абстрагирования от конкретного представления данных), что в итоге повышает эффективность конечной программы.TASM поддерживает следующие сложные типы данных:и массивы;ш структуры;^ объединения;ш записи.Разберемся более подробно с тем, как определить данные этих типов в программеи организовать работу с ними.МассивыДадим формальное определение: массив — структурированный тип данных, состоящий из некоторого числа элементов одного типа.Для того чтобы разобраться в возможностях и особенностях обработки массивов в программах на ассемблере, нужно ответить на следующие вопросы.Как описать массив в программе?Как инициализировать массив, то есть как задать начальные значения его элементов?ш Как организовать доступ к элементам массива?ii Как организовать выполнение типовых операций с массивами?Описание и инициализация массива в программеСпециальных средств описания массивов в программах ассемблера, конечно, нет.Чтобы использовать массив в программе, его нужно смоделировать одним из перечисленных далее способов.270:Глава 13.
Сложные структуры данных= Можно перечислить элементы массива в поле операндов одной из директивописания данных. При перечислении элементы разделяются запятыми. Например,;массив из 5 элементов. Размер к а ж д о г о элемента 4 байта:m a s dd 1 , 2 , 3 , 4 , 5^ Можно использовать оператор повторения D U P .
К примеру,;массив из 5 нулевых элементов. Размер каждого элемента 2 б а й т а :mas dw 5 dup (0)Такой способ определения используется для резервирования памяти с цельюразмещения и инициализации элементов массива.?: Можно использовать директивы LABEL и REPT. Пара этих директив позволяетоблегчить описание больших массивов в памяти и повысить наглядность такого описания. Директива REPT относится к макросредствам языка ассемблераи вызывает повторение указанное число раз строк, заключенных между директивой и строкой ENDM.
К примеру, определим массив байтов в области памяти,обозначенной идентификатором mas_b. В данном случае директива LABEL определяет символическое имя mas_b аналогично тому, как это делают директивырезервирования и инициализации памяти. Достоинство директивы LABEL —в том, что она не резервирует память, а лишь определяет характеристики объекта.В данном случае объект — это ячейка памяти. Используя несколько директивLABEL, записанных одна задругой, можно присвоить одной и той же областипамяти разные имена и типы, что и сделано в следующем фрагменте:п-0mas_blabelbyternas_wlabelwordrept4dw GflfOhen dmВ результате в памяти будет создана последовательность из четырех слов flfO.Эту последовательность можно трактовать как массив байтов или слов в зависимости от того, какое имя области мы будем использовать в программе — mas_bили mas_w."Чтобы инициализировать значениями область памяти и впоследствии трактовать ее как массив, можно использовать цикл.
Посмотрим па примере листинга 13.1, каким образом это делается.Листинг 13.1. Инициализация массива в цикле; prg 13 1.asmMASfTMODELSTACK. datames d bmas db:db.cedema i n:small2560ah,0dh,'Массив- " , " $ '10 dup (?);исходный массив0Массивыmovmovxormovmov271ax , @datads , axax, axex , 10si , eобнуление ахзначение счетчика цикла в схиндекс начального элемента в схgo:цикл и н и ц и а л и з а ц и иmov bh , 1i в bhmov mas [si] . bhзапись в массив iinc iинкремент ii ri с s iпродвижение к следующему элементу массиваloop goповторить цикл; вывод на экран получившегося массиваmov ex , 16mov si , 0mov ah, 09hlea dx , roesint.
21hshow:mov ah, 02hфункция вывода значения из al на экранmov dl . mas [si ]add dl , 30hпреобразование числа в символint 2 Ininc siloop showexi t :mov ax, 4c00hстандартный выходint 21 hendmai nконец программыДоступ к элементам массиваПри работе с массивами необходимо четко представлять себе, что нее элементымассива располагаются в памяти компьютера последовательно. Само по себе такое расположение ничего не говорит о назначении и порядке использования эчихэлементов. И только лишь программист с, помощью составленного им алгоритмаобработки определяет, как нужно трактовать последовательность байтов, составляющих массив. Так, одну и ту же область памяти можно трактовать одновременно и как одномерный, и как двухмерный массив. Все зависит только от алгоритм;.:обработки этих данных в конкретной программе.
Сами по себе данные не несутникакой информации о своем «смысловом», или логическом, типе. Помните обэтом принципиальном моменте.Те же соображения можно распространить и на индексы элементов массива.Ассемблер не подозревает пи об их существовании, пи об их численных смысловых значениях. Для того чтобы локализовать определенный элемент массива, к егоимени нужно добавить индекс. Так как мы моделируем массив, то должны позаботиться и о моделировании индекса. В языке ассемблера индексы массивов — этообычные адреса, но с ними работают особым образом. Другими словами, когда припрограммировании на ассемблере мы говорим об индексе, то, скорее, подразумеваем под этим не номер элемента в массиве, а некоторый адрес. Давайте еще разобратимся к описанию массива.