Массив как способ организации данных

Дадим формальное определение:

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

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

· Как описать массивв программе?

· Как инициализировать массив, то есть как задать начальные значения его элементов?

· Как организовать доступк элементам массива?

· Как организовать массивыс размерностью более одной?

· Как организовать выполнениетиповых операций с массивами?

Описание и инициализация массива в программе

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

1. Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми. К примеру:

;массив из 5 элементов.Размер каждого элемента 4 байта:

2. Используя оператор повторения dup. К примеру:

;массив из 5 нулевых элементов.

;Размер каждого элемента 2 байта:

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

3. Используя директивы labelиrept. Пара этих директив может облегчить описание больших массивов в памяти и повысить наглядность такого описания. Директиваreptотносится к макросредствам языка ассемблера и вызывает повторение указанное число раз строк, заключенных между директивой и строкой endm. К примеру, определим массив байт в области памяти, обозначенной идентификаторомmas_b. В данном случае директиваlabelопределяет символическое имяmas_b, аналогично тому, как это делают директивы резервирования и инициализации памяти. Достоинство директивыlabelв том, что она не резервирует память, а лишь определяет характеристики объекта. В данном случае объект — это ячейка памяти. Используя несколько директивlabel, записанных одна за другой, можно присвоить одной и той же области памяти разные имена и разный тип, что и сделано в следующем фрагменте:

mas_b label byte

mas_w label word

В результате в памяти будет создана последовательность из четырех слов f1f0. Эту последовательность можно трактовать как массив байт или слов в зависимости от того, какое имя области мы будем использовать в программе —mas_bилиmas_w.

4. Использование цикла для инициализации значениями области памяти, которую можно будет впоследствии трактовать как массив.

5. Посмотрим на примере листинга 2, каким образом это делается.

Листинг 2 Инициализация массива в цикле

mes db 0ah,0dh,’Массив- ‘,’$’

mas db 10 dup (?) ;исходный массив

xor ax,ax ;обнуление ax

mov cx,10 ;значение счетчика цикла в cx

mov si,0 ;индекс начального элемента в cx

go: ;цикл инициализации

mov mas[si],bh ;запись в массив i

inc i ;инкремент i

inc si ;продвижение к следующему элементу массива

loop go ;повторить цикл

;вывод на экран получившегося массива

mov ah,02h ;функция вывода значения из al на экран

add dl,30h ;преобразование числа в символ

mov ax,4c00h ;стандартный выход

end main ;конец программы

Доступ к элементам массива

При работе с массивами необходимо четко представлять себе, что все элементы массива располагаются в памяти компьютера последовательно.

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

Читайте также:  Лидокаин буфус способ применения

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

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

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

Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой dw, то есть она равна2байта. Чтобы получить доступ к третьему элементу, нужно к адресу массива прибавить6. Нумерация элементов массива в ассемблере начинается с нуля.

То есть в нашем случае речь, фактически, идет о 4-м элементе массива — 3, но об этом знает только программист; микропроцессору в данном случае все равно — ему нужен только адрес.

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

база + (индекс*размер элемента)

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

· индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется из двух компонентов:

o постоянного (базового)— указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;

o переменного (индексного)— указанием имени индексного регистра.

;поместить 3-й элемент массива mas в регистр ax:

· базовая индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется максимум из трех компонентов:

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

o переменного (базового)— указанием имени базового регистра;

o переменного (индексного)— указанием имени индексного регистра.

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

Напомним, что в качестве базового регистра может использоваться любой из восьми регистров общего назначения. В качестве индексного регистра также можно использовать любой регистр общего назначения, за исключением esp/sp.

Микропроцессор позволяет масштабировать индекс. Это означает, что если указать после имени индексного регистра знак умножения “*” с последующей цифрой 2, 4 или 8, то содержимое индексного регистра будет умножаться на 2, 4 или 8, то есть масштабироваться.

Применение масштабирования облегчает работу с массивами, которые имеют размер элементов, равный 2, 4 или 8 байт, так как микропроцессор сам производит коррекцию индекса для получения адреса очередного элемента массива. Нам нужно лишь загрузить в индексный регистр значение требуемого индекса (считая от 0). Кстати сказать, возможность масштабирования появилась в микропроцессорах Intel, начиная с модели i486. По этой причине в рассматриваемом здесь примере программы стоит директива .486. Ее назначение, как и ранее использовавшейся директивы.386, в том, чтобы указать ассемблеру при формировании машинных команд на необходимость учета и использования дополнительных возможностей системы команд новых моделей микропроцессоров.

Читайте также:  Фитолавин врк способ применения

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

Листинг 3. Просмотр массива слов с использованием

.data ;начало сегмента данных

mes1 db ‘не равен 0!$’,0ah,0dh

mes2 db ‘равен 0!$’,0ah,0dh

mes3 db 0ah,0dh,’Элемент $’

mas dw 2,7,0,0,1,9,3,6,0,8 ;исходный массив

.486 ;это обязательно

mov ds,ax ;связка ds с сегментом данных

xor ax,ax ;обнуление ax

mov cx,10 ;значение счетчика цикла в cx

mov esi,0 ;индекс в esi

mov dx,mas[esi*2] ;первый элемент массива в dx

cmp dx,0 ;сравнение dx c 0

je equal ;переход, если равно

not_equal: ;не равно

mov ah,09h ;вывод сообщения на экран

mov ah,02h ;вывод номера элемента массива на экран

inc esi ;на следующий элемент

dec cx ;условие для выхода из цикла

jcxz exit ;cx=0? Если да — на выход

jmp compare ;нет — повторить цикл

mov ah,09h ;вывод сообщения mes3 на экран

mov ah,09h ;вывод сообщения mes2 на экран

inc esi ;на следующий элемент

dec cx ;все элементы обработаны?

mov ax,4c00h ;стандартный выход

end main ;конец программы

Еще несколько слов о соглашениях:

· Если для описания адреса используется только один регистр, то речь идет о базовой адресациии этот регистр рассматривается какбазовый:

;переслать байт из области данных, адрес

которой находится в регистре ebx:

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

;сложить содержимое eax с двойным словом в памяти

;по адресу mas + (ebx)*4

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

· Помните, что применение регистров ebp/bpиesp/spпо умолчанию подразумевает, что сегментная составляющая адреса находится в регистреss.

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

;адрес операнда равен [mas+(ebx)+(ecx)*2]

;адрес операнда равен [(ebx)+8+(ecx)*4]

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

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

Читайте также:  Способы продажи авиабилетов кратко

Листинг 4. Обработка массива элементов с нечетной длиной

MODEL small ;модель памяти

STACK 256 ;размер стека

.data ;начало сегмента данных

N=5 ;количество элементов массива

mas db 5 dup (3 dup (0))

.code ;сегмент кода

main: ;точка входа в программу

xor ax,ax ;обнуление ax

mov dl,mas[si] ;первый байт поля в dl

inc dl ;увеличение dl на 1 (по условию)

mov mas[si],dl ;заслать обратно в массив

add si,3 ;сдвиг на следующий элемент массива

Источник

Массивы как способ организации данных

Структура данных массив. Понятие массива

До сих пор мы работали с простыми переменными. Простая переменная харак­теризуется тем, что под ее именем в памяти хранится только одна величина. Однако есть задачи, в которых необходимо под одним именем задавать сразу несколько вели­чин одного типа.

Пример.

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

var al,a2,a3: integer;

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

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

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

. Чтобы получить доступ к нужному ящику, нужно указать имя массива и его ин­декс. Индекс записывается в квадратных скобках. Имя массива записывается по тем же правилам, что и имя простой переменной. Например: а[3] — обращение к 3-му элементу массива. Массив относится к структурированным типам данных.

Писание массива

Если при решении задачи используется массив, то в программе он должен быть опи­сан либо в разделе переменных, либо в разделе типов. Описание массива в разделе переменных.

VAR : ARRAY [Tl ] OF T2 ;

Здесь ARRAY (массив); OF (из) — служебные слова; Tl — тин индекса, в качестве кото­рого может быть любой простой тип, кроме стандартных типов INTEGER и REAL; T2 -тип элементов массива, допустимый в языке Паскаль (любой, кроме файлового). Примеры:

VAR A: ARRAY [1 ..5] OF REAL;

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

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

VAR A: ARRAY [5] OF REAL;

или VAR A: ARRAY [INTEGER] OF REAL;

Если несколько массивов имеют одинаковый тип индекса и одинаковый базовый тип, то допускается следующее описание:

VAR A,B,C: ARRAY [1..5] OF REAL;

здесь объявлено 3 массива А,В,С действительных чисел.

Внимание !

дй Нельзя путать понятия ‘индекс’ и ‘тип индекса’. Тип индекса используется в разделе описания массива, а индекс указывается в разделе операторов для обозначения кон­кретных элементов массива. В качестве индекса может быть выражение, частным слу­чаем которого является константа или переменная.

Не нашли, что искали? Воспользуйтесь поиском:

Источник

Оцените статью
Разные способы