Шаг 43.
Доступ к элементам массива

    На этом шаге мы рассмотрим способы доступа к элементам массива.

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

   mas   DW       0,1,2,3,4,5                             .

    Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой DW, то есть она равна 2 байта. Чтобы получить доступ к третьему элементу, нужно к адресу массива прибавить 6. Нумерация элементов массива в ассемблере начинается с нуля. То есть, в нашем случае речь, фактически, идет о 4-м элементе массива. В общем случае для получения адреса элемента в массиве необходимо начальный (базовый) адрес массива сложить с произведением индекса (номер элемента минус единица) этого элемента на размер элемента массива:

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

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

  1. Индексная адресация со смещением - режим адресации, при котором эффективный адрес формируется из двух компонентов:
    • постоянного (базового) - указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;
    • переменного (индексного) - указанием имени индексного регистра.
    К примеру:
           .    .    .    .    .
        mas    DW      0,1,2,3,4,5
           .    .    .    .    .
               MOV   SI,4
               ;Поместить 3-й элемент массива mas в регистр AX. 
               MOV   AX, mas[SI]
    
  2. Если для описания адреса используется только один регистр, то речь идет о базовой адресации и этот регистр рассматривается как базовый:
           .    .    .    .    .
        mas    DW      0,1,2,3,4,5
         .    .    .    .    .
               LEA BX, mas ;Поместить в BX адрес начала массива mas.
               MOV AX,[BX] ;Переслать начальный элемент массива в AX.
               ADD  BX,2;Разместить в BX адрес следующего элемента массива.
    
  3. Если для задания адреса в команде используется прямая адресация (в виде идентификатора) в сочетании с одним регистром, то речь идет об индексной адресации. Для получения адреса нужного элемента массива можно использовать масштабирование:
               ADD  AX,mas[BX*2] ;Сложить содержимое AX со словом 
                                 ;в памяти по адресу mas + (BX)*2.
    
  4. Если для описания адреса используются два регистра, то речь идет о базово-индексной адресации. Левый регистр рассматривается как базовый, а правый - как индексный. В общем случае это не принципиально, но если мы используем масштабирование с одним из регистров, то он всегда является индексным. Но лучше придерживаться определенных соглашений. Помните, что применение регистров BP и SP по умолчанию подразумевает, что сегментная составляющая адреса находится в регистре SS.

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

    К примеру:

    MOV AX,mas[BX][CX*2] ;Адрес операнда равен [mas+(BX)+(CX)*2].
    SUB  DX,[BX+8][CX*4] ;Адрес операнда равен [(BX)+8+(CX)*4].

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

    На следующем шаге мы приведем пример программы с использованием массивов.




Предыдущий шаг Содержание Следующий шаг