Способы адресации, используемые при работе с массивами 


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



ЗНАЕТЕ ЛИ ВЫ?

Способы адресации, используемые при работе с массивами



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

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

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

К примеру:

Mas dw 0,1,2,3,4,5

...

Mov si,4

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

mov ax,mas[si]

 

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

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

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

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

 

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

Mov eax,mas[bx][si]

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

 


Микропроцессор позволяет масштабировать индекс. Необходимость в масштабировании возникает при работе с массивами, которые имеют размер элементов, равный 2, 4 или 8 байтам.

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

Пример 6: Просмотр массива слов с использованием масштабирования

;prg_12_2.asm. Для DOS16.

MASM

MODEL small

STACK 256

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

;тексты сообщений:

mes1 db "не равен 0!$",10,13

mes2 db "равен 0!$",10,13

mes3 db 10,13,'Элемент $'

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

.code

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

start:

mov ax,@data

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

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

prepare:

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

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

compare:

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

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

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

not_equal:;не равно

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

lea dx,mes3

int 21h

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

mov dx,si

add dl,30h

int 21h

mov ah,09h

lea dx,mes1

int 21h

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

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

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

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

equal:;равно 0

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

lea dx,mes3

int 21h

mov ah,02h

mov dx,si

add dl,30h

int 21h

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

lea dx,mes2

int 21h

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

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

jcxz exit

jmp compare

exit:

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

int 21h

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

 


Возможны следующие случаи при адресации массивов:

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

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

; регистре ebx

mov al,[ebx]

 

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

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

; mas + (ebx)*4

add eax,mas[ebx*4]

 

3) если для описания адреса используются два регистра, то такая адресация называется базово-индексной адресацией. Левый регистр рассматривается как базовый, а правый — как индексный.

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

 

К примеру:

mov ax,mas[ebx][ecx*2]

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

...

sub dx,[ebx+8][ecx*4]

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

 

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


Пример 7: Обработка массива элементов с нечетной длиной. Размер элемента массива в три байта. Массив сформировать самостоятельно, следующим образом: первый элемент массива равен Е3 1111h=14 881 041d, все последующие трёхбитные элементы массива равны inc(E3 1111h). В памяти сформировать массив из 16 трёхбитных элемента. Увеличить на единицу в каждом элементе массива значение первого байта. Вывести измененный массив на экран в одну строку. Примечание: Е4 1111h=14 946 577d.

;---------------------------------------------------------------------------

; Версия для Win32 (tri.asm)

.386

.model flat, stdcall

includelib import32.lib

extrn ExitProcess:PROC

extrn MessageBoxA:PROC

.data

Ttl db 'Massiv',0h

mas db 16 dup (3 dup (0)); 48 элементов в массиве

; следующую строчку 2 байта 0ah,0dh

mes1 db 'Massiv: ',0ah,0dh

Msg db 150 dup (?)

 

masVivod db 85 dup (?);

var dd 0E31111h

var2 dd?

var3 dd 00000000h

i db 1

N db 16

tabl db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h

k dd 0

 

.code

start:

xor ecx,ecx;обнуление есx

xor edx,edx

mov cl,N;значение счетчика цикла в cl

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

;-------------------------------------------------------------------------------------------------

; Заполнение элементов массива значениями var E31111h++

mov eax,var

mov var2,eax

go2:

xor eax,eax

mov al,byte ptr [var+2]; al=E3h

mov mas[esi],al

inc esi

mov al,byte ptr [var+1]; al=11h

mov mas[esi],al

inc esi

mov al,byte ptr [var]; al=11h

mov mas[esi],al

inc esi

inc var

loopnz go2

 

;--------------------------------------------------------------------------------------------

; Изменение первого байта в каждом элементе массива

mov esi,0;0 в si

xor ecx,ecx

mov cl,N

go:

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

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

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

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

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

 

mov cl,N

mov edi,0

mov esi,0

 

go1:

;----------------------------------------------------------------------------

; Переносим трёхбитное число из массива mas в регистр еах для перевода в

; десятичное число

xor eax,eax

xor ebx,ebx

mov ah,mas[esi]

mov al,mas[esi+1]

mov bl,mas[esi+2]

shl eax,8

add eax,ebx

add esi,3

;-------------------------------------------------------------------------------

; Перевод в десятичную систему исчисления трёхбайтного числа из eax и

; запись десятичного числа в память

push esi

mov ebx,eax

xor eax,eax

xor edx,edx

xor edi,edi

mov dl,i

mov al,8

mul dl

add eax,k

mov edi,eax

xor esi,esi

mov esi,10

push edi

mov eax,ebx

lp2: xor edx,edx

div esi

xchg eax,edx

add al,'0'

mov byte ptr [Msg+edi],al

xchg eax,edx

dec edi

or eax,eax

jne lp2

;-------------------------------------------------------------------------------------

; Ставим символ ";" в качестве разделителя после каждого числа

pop edi

mov byte ptr [Msg+edi+1],';'

inc i

inc k

pop esi

loopnz go1

;---------------------------------------------------------------------------------------

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

push 0h

push offset Ttl

push offset [Msg+1]

push 0h

call MessageBoxA

push 0h

call ExitProcess

end start

 

Результат:

_______________________________________________________________

Самостоятельно на практике: Создать массив с элементами нечетной длины. Размер элемента массива в три байта. Массив сформировать самостоятельно, следующим образом: первый элемент массива равен Е3 1111h=14 881 041d, все последующие трёхбайтные элементы массива равны inc(E3 1111h). В памяти сформировать массив из 16 трёхбайтных элемента. Увеличить на единицу в каждом элементе массива значение второго байта. Вывести измененный массив на экран построчно так, чтобы в строке было 4 элемента массива.

 


Двумерные массивы

Обращение к элементам двумерного массива в памяти как к строкам или как к столбцам зависит от алгоритма обработки двумерного массива.

Если последовательность однотипных элементов в памяти трактуется как двумерный массив, расположенный по строкам, то адрес элемента (i, j) вычисляется по формуле:

(база + количество_элементов_в_строке * размер_элемента * i+

+j* размер_элемента)

 

Здесь i = 0...n-l указывает номер строки, a j = 0...m-l указывает номер столбца.

Например, пусть имеется массив чисел (размером в 1 байт) mas(i,j) с размерностью 4 X 4 (i = 0...3, j = 0...3):

23 04 05 67

05 06 07 99

67 08 09 23

87 09 00 08

В памяти элементы этого массива будут расположены в следующей последовательности:

23 04 05 67 05 06 07 99 67 08 09 23 87 09 00 08

Если необходимо трактовать эту последовательность как двумерный массив и извлечь, например, элемент mas(2, 3) = 23, то, убедимся что:

Полный адрес mas(2, 3) = mas + 4 * 1 * 2 + 3*1 = mas + 11

 

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

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

mov ax,mas[ebx][esi]

5) сочетание двух индексных регистров, один из которых является и базовым, и индексным одновременно, а другой — только индексным:

mov ax,[edi][esi]

 

Пример 1: Фрагмент программы выборки элемента массива mas(2,3) и запись его значения в регистр al.

Data

Mas db 23,4,5,67,5,6,1,99,67,8,9,23,87,9,0,8

i=2

j=3

; 23 04 05 67

; 05 06 01 99

; 67 08 09 23

; 87 09 00 08

Code

...

mov si,4*1*i; 1 – размер элемента массива 1 байт

mov di,j*1; 1 - размер элемента массива 1 байт

mov al,mas[si][di];в аl элемент mas(2,3)=23

Пример 2: Фрагмент программы выборки элемента массива mas(2,3) и его обнуления

Data

Mas dw 23,4,5,67,5,6,1,99,67,8,9,23,87,9,0,8

i=2

j=3

; 00 23 00 04 00 05 00 67

; 00 05 00 06 00 01 00 99

; 00 67 00 08 00 09 00 23

; 00 87 00 09 00 00 00 08

Code

...

mov si,4*2*i; =16; 2 – размер элемента массива 2 байта

mov di,j*2; =6

mov ах,mas[si][di]; в аx элемент mas(2,3)=mas+16+6=mas+22

; ax=0023



Поделиться:


Последнее изменение этой страницы: 2016-09-13; просмотров: 1212; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 54.208.238.160 (0.047 с.)