Пятница, 26.04.2024, 16:38
 

Меню сайта

Форма входа
Друзья сайта
Статистика
Наш опрос
Нужен ли нашему потоку сайт?
Всего ответов: 87
[Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Модератор форума: SPA, FeniX  
Форум » Помощь студентам! » Assembler » Массивы в Ассемблере
Массивы в Ассемблере
AdminДата: Вторник, 11.03.2008, 13:40 | Сообщение # 1
General Admin
Группа: Администраторы
Сообщений: 502
Награды: 0
Статус: OffLine
Помощь тем, кто хочет сделать 5-ю лабораторную работу по Ассемблеру:

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

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

Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми. К примеру:
;массив из 5 элементов.Размер каждого
элемента 4 байта:
mas dd 1,2,3,4,5

Используя оператор повторения dup. К примеру:
;массив из 5 нулевых элементов.
;Размер каждого элемента 2 байта:
mas dw 5 dup (0)

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

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

Использование цикла для инициализации значениями области памяти, которую можно будет впоследствии трактовать как массив.
Посмотрим на примере листинга 2, каким образом это делается.
Листинг 2 Инициализация массива в цикле
;prg_12_1.asm
MASM
MODEL small
STACK 256
.data
mes db 0ah,0dh,'Массив- ','$'
mas db 10 dup (?) ;исходный массив
i db 0
.code
main:
mov ax,@data
mov ds,ax
xor ax,ax ;обнуление ax
mov cx,10 ;значение счетчика цикла в cx
mov si,0 ;индекс начального элемента в cx
go: ;цикл инициализации
mov bh,i ;i в bh
mov mas[si],bh ;запись в массив i
inc i ;инкремент i
inc si ;продвижение к следующему
;элементу массива
loop go ;повторить цикл
;вывод на экран получившегося массива
mov cx,10
mov si,0
mov ah,09h
lea dx,mes
int 21h
show:
mov ah,02h ;функция вывода значения
;из al на экран
mov dl,mas[si]
add dl,30h ;преобразование числа в символ
int 21h
inc si
loop show
exit:
mov ax,4c00h ;стандартный выход
int 21h
end main ;конец программы

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

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

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

Давайте еще раз обратимся к описанию массива. К примеру, в программе статически определена последовательность данных: mas dw 0,1,2,3,4,5

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

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

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

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

индексная адресация со смещением — режим адресации, при котором эффективный адрес формируется из двух компонентов:
постоянного (базового) — указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива;
переменного (индексного) — указанием имени индексного регистра.
К примеру: mas dw 0,1,2,3,4,5
...
mov si,4
;поместить 3-й элемент массива mas в регистр ax:
mov ax,mas[si]

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

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

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

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

В качестве примера использования масштабирования рассмотрим листинг 3, в котором просматривается массив, состоящий из слов, и производится сравнение этих элементов с нулем. Выводится соответствующее сообщение. Листинг 3. Просмотр массива слов с использованием
масштабирования
;prg_12_2.asm
MASM
MODEL small
STACK 256
.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 ;исходный массив
.code
.486 ;это обязательно
main:
mov ax,@data
mov ds,ax ;связка ds с сегментом данных
xor ax,ax ;обнуление ax
prepare:
mov cx,10 ;значение счетчика цикла в cx
mov esi,0 ;индекс в esi
compare:
mov dx,mas[esi*2] ;первый элемент массива в dx
cmp dx,0 ;сравнение dx c 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 cx ;условие для выхода из цикла
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 cx ;все элементы обработаны?
jcxz exit
jmp compare
exit:
mov ax,4c00h ;стандартный выход
int 21h
end main ;конец программы

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

Если для описания адреса используется только один регистр, то речь идет о базовой адресации и этот регистр рассматривается как базовый: ;переслать байт из области данных, адрес
которой находится в регистре ebx:
mov al,[ebx]

Если для задания адреса в команде используется прямая адресация (в виде идентификатора) в сочетании с одним регистром, то речь идет об индексной адресации. Регистр считается индексным, и поэтому можно использовать масштабирование для получения адреса нужного элемента массива: add eax,mas[ebx*4]
;сложить содержимое eax с двойным словом в памяти
;по адресу mas + (ebx)*4

Если для описания адреса используются два регистра, то речь идет о базово-индексной адресации. Левый регистр рассматривается как базовый, а правый — как индексный. В общем случае это не принципиально, но если мы используем масштабирование с одним из регистров, то он всегда является индексным. Но лучше придерживаться определенных соглашений.
Помните, что применение регистров ebp/bp и esp/sp по умолчанию подразумевает, что сегментная составляющая адреса находится в регистре ss.
Заметим, что базово-индексную адресацию не возбраняется сочетать с прямой адресацией или указанием непосредственного значения. Адрес тогда будет формироваться как сумма всех компонентов.

К примеру: mov ax,mas[ebx][ecx*2]
;адрес операнда равен [mas+(ebx)+(ecx)*2]
...
sub dx,[ebx+8][ecx*4]
;адрес операнда равен [(ebx)+8+(ecx)*4]

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

Рассмотрим пример работы с массивом из пяти трехбайтовых элементов (листинг 4). Младший байт в каждом из этих элементов представляет собой некий счетчик, а старшие два байта — что-то еще, для нас не имеющее никакого значения. Необходимо последовательно обработать элементы данного массива, увеличив значения счетчиков на единицу. Листинг 4. Обработка массива элементов с нечетной длиной
;prg_11_3.asm
MASM
MODEL small ;модель памяти
STACK 256 ;размер стека
.data ;начало сегмента данных
N=5 ;количество элементов массива
mas db 5 dup (3 dup (0))
.code ;сегмент кода
main: ;точка входа в программу
mov ax,@data
mov ds,ax
xor ax,ax ;обнуление ax
mov si,0 ;0 в si
mov cx,N ;N в cx
go:
mov dl,mas[si] ;первый байт поля в dl
inc dl ;увеличение dl на 1 (по условию)
mov mas[si],dl ;заслать обратно в массив
add si,3 ;сдвиг на следующий элемент массива
loop go ;повтор цикла
mov si,0 ;подготовка к выводу на экран
mov cx,N
show: ;вывод на экран содержимого
;первых байт полей
mov dl,mas[si]
add dl,30h
mov ah,02h
int 21h
loop show
exit:
mov ax,4c00h ;стандартный выход
int 21h
end main ;конец программы



Умное лицо - это еще не признак ума. Все глупости в мире совершаются именно с этим выражением лица... Улыбайтесь господа, улыбайтесь!
 
4elove4ekДата: Суббота, 20.12.2008, 20:50 | Сообщение # 2
Лейтенант
Группа: VIP пользователи!
Сообщений: 76
Награды: 0
Замечания: 0%
Статус: OffLine
А есть подобный материал, только для работы со строками??! Например, подсчитать наибольшее количество подряд стоящих пробелов или количество гласных букв в стоке?

Добро обязательно победит Зло! Поставит его на колени и зверски убъёт!
 
SPAДата: Воскресенье, 21.12.2008, 01:14 | Сообщение # 3
Angel
Группа: Администраторы
Сообщений: 163
Награды: 0
Статус: OffLine
На этот вопрос может ответить только General Admin - моя сестра smile
Потому что, я не учусь с ними, и даже никого из них не знаю...
Но, наверное, должен быть...
Они же это тоже должны были изучать smile


 
4elove4ekДата: Воскресенье, 21.12.2008, 16:13 | Сообщение # 4
Лейтенант
Группа: VIP пользователи!
Сообщений: 76
Награды: 0
Замечания: 0%
Статус: OffLine
Quote (SPA)
Они же это тоже должны были изучать

Очень на это надеюсь, а то сейчас в универе такая запарка....как всегда всё отлаживала до лучших времён, а они не настали....хоть бери и вешайся cry


Добро обязательно победит Зло! Поставит его на колени и зверски убъёт!
 
4elove4ekДата: Понедельник, 22.12.2008, 13:57 | Сообщение # 5
Лейтенант
Группа: VIP пользователи!
Сообщений: 76
Награды: 0
Замечания: 0%
Статус: OffLine
Quote (SPA)
General Admin - моя сестра

А я думала вы однокурсницы faint


Добро обязательно победит Зло! Поставит его на колени и зверски убъёт!
 
SPAДата: Понедельник, 22.12.2008, 19:58 | Сообщение # 6
Angel
Группа: Администраторы
Сообщений: 163
Награды: 0
Статус: OffLine
Вот я нашла в Интернете какой-то пример на строки:
Имеется строка-предложение из нескольких слов. Написать процедуру осуществляющую запись тех же строк словами переписанными с конца наперед. Дополнительных массивов не использовать. Осуществить вывод исходной строки и сформированной.
http://forum.codenet.ru/showthread.php?t=48492


 
SPAДата: Понедельник, 22.12.2008, 20:01 | Сообщение # 7
Angel
Группа: Администраторы
Сообщений: 163
Награды: 0
Статус: OffLine
А тут теория про строки:
http://knightsoflight.ru/index/0-39

Самое интересное, что меня поставили здесь модером... а я Ассемблера вообще не знаю smile


 
AdminДата: Понедельник, 22.12.2008, 21:22 | Сообщение # 8
General Admin
Группа: Администраторы
Сообщений: 502
Награды: 0
Статус: OffLine
Quote (4elove4ek)
А есть подобный материал, только для работы со строками??! Например, подсчитать наибольшее количество подряд стоящих пробелов или количество гласных букв в стоке?

Да, материал по строкам есть, хотя я не совсем уверена, что он поможет.
Assembler у нас шел на зачет, и мы его не изучали очень сильно подробно…
Потому что, наша специальность КС- компьютерные системы. Мы не программисты, хотя и программирование тоже изучали; у нас уклон больше на аппаратную часть ПК, сети, операционные системы и т.д

Вот несколько примеров программ, которые мы писали:

Пример1

Есть строка STR1, состоящая из ‘ABCDE’ и строка STR2, состоящая из ‘12345’ Необходимо сформировать строку ‘SCDE*543!’

Программа

STR1 db ‘ABCDE’
STR2 db ‘12345’
STR3 db 20 dup(?)

.code
Mov ax,@data
Mov ds,ax
Mov es,ax

LEA SI, STR1+1
LEA DI,STR2
Mov cx,4
REP MOVSB
Mov al,’*’
STOSB
LEA SI, STR2+4
Mov cx,3
STD
LODSB
CLD
STOSB
LOP C
Mov al,’!’
STOS B

Пример 2
Из строк, данных в примере 1, необходимо сформировать строку ‘A4-B3-C2-D1-‘

Программа

STR1 db ‘ABCDE’
STR2 db ‘12345’
STR3 db 20 dup(?)

.code
Mov ax,@data
Mov ds,ax
Mov es,ax

LEA SI,STR1
LEA DI, STR3
LEA BX,STR2+3
MOV CX,4

C:
CLD
MOVSB
XCHC BX,SI
STD
LODSB
CLD
STOSB
MOV AL, ‘-‘
STOSB
XCHC BX,SI
LOOP C


Умное лицо - это еще не признак ума. Все глупости в мире совершаются именно с этим выражением лица... Улыбайтесь господа, улыбайтесь!
 
AdminДата: Понедельник, 22.12.2008, 21:30 | Сообщение # 9
General Admin
Группа: Администраторы
Сообщений: 502
Награды: 0
Статус: OffLine
Вот еще пример:
Прикрепления: Symbols.asm (1.6 Kb)


Умное лицо - это еще не признак ума. Все глупости в мире совершаются именно с этим выражением лица... Улыбайтесь господа, улыбайтесь!
 
AdminДата: Понедельник, 22.12.2008, 21:51 | Сообщение # 10
General Admin
Группа: Администраторы
Сообщений: 502
Награды: 0
Статус: OffLine
Я, для тебя, добавила в каталог файлов книгу по Assembler. Там есть примеры.
Питер Абель: "АССЕМБЛЕР И ПРОГРАММИРОВАНИЕ ДЛЯ IBM PC"

http://nmu-cs06.at.ua/load/1-1-0-8


Умное лицо - это еще не признак ума. Все глупости в мире совершаются именно с этим выражением лица... Улыбайтесь господа, улыбайтесь!
 
4elove4ekДата: Вторник, 23.12.2008, 16:29 | Сообщение # 11
Лейтенант
Группа: VIP пользователи!
Сообщений: 76
Награды: 0
Замечания: 0%
Статус: OffLine
ОГО сколько всего, СПАСИБО flower flower flower

Добро обязательно победит Зло! Поставит его на колени и зверски убъёт!
 
Форум » Помощь студентам! » Assembler » Массивы в Ассемблере
  • Страница 1 из 1
  • 1
Поиск:




Администратор сайта - Алена © 2024

Ваш
IP: 18.191.5.239