48264 (597389), страница 6
Текст из файла (страница 6)
Одномерные массивы
Все элементы массива располагаются в памяти последовательно
Описание элементов массива
mas db 1,2,3,4,5
mas dw 5 dup (0)
Доступ к элементам массива
mov ax,mas[si] ; в si номер элемента в массиве
mov mas[si], ax ; в di номер элемента в массиве
Используя команды i486 можно использовать адресацию с масштабированием, при размере элементов больше байта
Mov ax, mas[si*2] ;
Пример программы Найти в строке хотя бы один нулевой элемент
model small
.stack 100h
.data
bufer dw 25 ;формирую размер буфера для ввода строки
mas dw 25 dup (' ') ;формирую буфер
adr dw bufer ;описываю адрес
subj1 db ‘в строке найден нулевой элемент', '$'
subj2 db ‘в строке не найден нулевой элемент', '$'
.code
main:
mov ax,@data
mov ds,ax
mov ah,0ah
mov dx, adr
int 21h ; ввод строки с клавиатуры
;поиск нулевого элемента
xor si, si
mov cx, mas[si] ;загружаем в сх количество элементов в строке
mov ax, 030h ;в ax загружаем ASCII код нуля
m1: inc si либо inc si
inc si cmp ax, mas[si*2]
cmp ax, mas[si]
je m2 ;если в строке найдем нулевой элемент, то выходим из цикла на вывод subj1
loop m1
;нормальный выход из цикла означает что в строке нет нулевых элементов
mov ah,09h
lea dx, subj2
int 21h
jmp exit
m2: mov ah, 09h
lea dx,subj1
int 21h
exit: mov ax,4c00h
int 21h
end main
Двумерные массивов
!Специальных средств для описания двумерных массивов в ассемблере нет!
Двумерный массив описывается также как и одномерный массив, отличие заключается в трактовке расположения элементов. Пусть последовательность элементов трактуется как двумерный массив, расположенный по строкам, тогда адрес элемента [i,j] вычисляется так
База+колич_элем_строке*размер_элем*I+j
Для определения базы используют имя массива, для второго слагаемого регистр bx , для третьего si, это базово-индексная адресация.
Описание массива:
Mas1 db 10 dup (3 dup (?))
Mas2 db 1,2,3,4,5
3,4,5,6,7
4,7,9,2,0
Пример поиска максимального элемента в каждой строке однобайтного массива mas, размером 5*10, с занесением максимальных элементов в массив max (1*5). Инициализацию массива mas рассматривать не будем.
…
xor di, di ;обнуляем индексы массива max
xor bx, bx ;обнуляем индексы строк массива mas
xor si, si ;обнуляем индексы столбцов массива mas
mov cx,5 ;в cx количество строк, внешний цикл
m1: push cx
mov cx, 10 ;в сх количество столбцов, внутренний цикл
mov al, mas[si+bx];первый элемент из 1 строки mas в аl
m2: inc si
cmp al, mas[si+bx] ;сравниваем со следующим элем. строки
jb m3 ;если меньше на m3
mov al, mas[si+bx] ;иначе в аl заносим больший элемент
m3: loop m2 ;после выхода из цикла в ах максимальный элемент в данной строке
mov max[di],al ;кладем максимальный элемент в массив max
inc di
xor si,si ;обнуляем номер столбца
add bx, 10 ;переходим на следующую строку
pop cx ;достаем сх
loop m1
…
Структура – это тип данных, состоящий из фиксированного числа элементов разного типа.
Для использования структур в программе необходимо выполнить три действия:
-
Задать шаблон структуры. По смыслу это означает определение нового типа данных (схемы или шаблона), который впоследствии можно использовать для определения переменных этого типа. Память при этом не выделяется, это информация для транслятора о расположении полей и их значению по умолчанию.
Синтаксис описания шаблона структуры:
имя_структуры STRUC
; последовательность директив описания данных dd,dw,db…
-
имя_структуры ENDS
-
Определить экземпляр структуры. Этот этап подразумевает инициализацию конкретной переменной заранее определенной (с помощью шаблона) структурой. В данном случае транслятору дается указание выделить память и присвоить этой области символическое имя.
-
Описать структуру в программе можно только один раз, а определить – любое количество раз.
Определение данных с типом структуры имеет следующий вид:
-
[имя переменной] имя_структуры
-
Организовать обращение к элементам структуры.
-
Для того чтобы сослаться в команде на поле некоторой структуры, используется следующее выражение:
-
имя_переменной.имя_поля_структуры,
-
Фрагмент программы. Найти из списка студентов отличника по всем предметам.
-
Model small
-
.586p
-
Stud struc
-
Name db 20 dup (‘’)
-
Phisika db ?
-
Matem db ?
-
Stud ends
-
.data
Bufer Stud ;зарезервировали пустую структуру
S1 Stud
S2 Stud
S3 Stud <”Сидоров”,’5’,’2’,’5’>
…
mov bx, offset s1
mov al, [bx].Phisika
-
cmp al, ‘5’
-
jne m2
mov al, [bx].Matem
-
cmp al, ‘5’
-
jne m2
-
;нашли одного из отличников, надо вывести его фамилию
-
m2: mov al, s2.Phisika ;ищем следующего отличника
-
mov ah, s2.Matem
-
cmp ax, ‘55’
-
jne m3
-
;нашли одного из отличников, надо вывести его фамилию
-
m3: ;ищем следующего отличника
Объединение - тип данных, позволяющий трактовать одну и ту же область памяти как имеющую разные типы и имена.
Описание объединений в программе напоминает описание структур, то есть сначала описывается шаблон, в котором с помощью директив описания данных перечисляются имена и типы полей:
имя_объединения UNION
имя_объединения ENDS
Отличие объединений от структур состоит, в частности, в том, что при определении переменной типа объединения память выделяется в соответствии с размером максимального элемента. Обращение к элементам объединения происходит по их именам, но при этом нужно, конечно, помнить о том, что все поля в объединении накладываются друг на друга.
Одновременная работа с элементами объединения исключена. В качестве элементов объединения можно использовать и структуры.
-
Model small
-
.586p
-
st union
-
stu1 dw ?
-
stu2 db ?
-
stu3 dd ?
-
st ends
-
.data
-
q st <> ;пустое объединение
-
z st <12ffh> ;заполнили объединение значением
-
…
-
mov q.stu2, al ;в переменную положили содержимое регистра al
-
mov q.stu3, edx
-
mov bx, z.stu1
-
mov dx, offset q.stu1
-
Запись - структурный тип данных, состоящий из фиксированного числа элементов длиной от одного до нескольких бит. При описании записи для каждого элемента указывается его длина в битах и, что необязательно, некоторое значение. Суммарный размер записи определяется суммой размеров ее полей и не может быть более 8, 16 или 32 бит. Если суммарный размер записи меньше указанных значений, то все поля записи “прижимаются” к младшим разрядам
-
Использование записей в программе, так же, как и структур, организуется в три этапа:
-
Описание шаблона записи
-
имя_записи RECORD
2. Для использования шаблона записи в программе необходимо определить переменную с типом данной записи, для чего применяется следующая синтаксическая конструкция (рис. 7):
-
3. Организация работы с записями. Обычные механизмы адресации бессильны, поскольку они работают на уровне байтов, а не отдельных битов.
-
каждому имени элемента записи ассемблер присваивает числовое значение, равное количеству сдвигов вправо, которое нужно произвести, для того чтобы этот элемент оказался прижатым к началу ячейки памяти;
-
размер элемента записи в битах можно узнать с помощью оператора width;
-
оператор mask позволяет локализовать биты нужного элемента записи;
-
все действия по преобразованию элементов записи производятся с помощью логических команд;
-
команда setfield устанавливает значение некоторого поля записи
setfield имя_элемента_записи регистр_ назначение, регистр_источник
-
команда getfield осуществляет выборку некоторого поля записи
getfield имя_элемента_записи регистр_назначение, регистр_ источник
Процедуры. Макрокоманды
-
Процедура, часто называемая подпрограммой, - это правильным образом оформленная совокупность команд, которая будучи однократно описана, при необходимости может быть вызвана в любом месте программы. Процедура представляет собой группу команд для решения конкретной подзадачи и обладает средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку. В простейшем случае программа может состоять из одной процедуры.
-
Описание процедуры может размещается в любом месте программы, но таким образом чтобы на нее случайным образом не попало управление:
-
в начале программы, до первой исполняемой команды;
-
в конце, после команды возвращающей управление операционной системе;
-
промежуточный вариант, тело процедуры располагается внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход процедуры командой jmp;
-
в другом модуле.
-
Синтаксис описания процедуры:
-
Имя_процедуры PROC заголовок
-
Команды, директивы тело процедуры
-
[ret] возврат из процедуры
-
[имя_процедуры] ENDP конец процедуры
-
Вызов процедуры осуществляется командой
-
CALL [модификатор] имя_процедуры
-
Команда call передает управление по адресу с символическим адресом имя_процедуры, с сохранением в стеке адреса возврата, команды следующей после команды call.
-
Возврат из процедуры осуществляется по команде
-
RET [число]
-
Команда ret считывает адрес возврата из стека и загружает его в регистры cs и ip/eip, возвращая таким образом управление команде, следующей за командой call. Число – необязательный параметр, обозначающий количество элементов, удаляемых из стека при возврате из процедуры. Размер элемента зависит от используемой модели сегментации 32 или 16 разрядной.
-
Передача аргументов из/в процедуру может осуществляться через регистры, переменные или стек.
-
Пример.
-
Model small
-
.stack 100h
-
.data
-
w db 25 dup (?)
-
.code
-
vvod proc
-
mov ah, 0ah
-
lea dx, w
-
int 21h
-
ret
-
vvod endp
-
main:
-
…
-
Call schet
-
Call vvod
-
…
-
exit:
-
mov ax,4c00h
-
int 21h
-
schet proc
-
..
-
ret
-
schet endp
-
end main
-
-
Макрокоманда является одним из многих механизмов замены текста программы. С помощью макрокоманды в текст программы можно вставлять последовательности строк и привязывать их к месту вставки.
-
Макрокоманда представляет собой строку, содержащую некоторое имя – имя макрокоманды, предназначенное для того, чтобы быть замещенным одной или несколькими другими строками при трансляции.
Для работы с макрокомандой вначале необходимо задать ее шаблон-описание, так называемое макроопределение.
Имя_макрокоманды MACRO [список_формальных_аргументов]
12ffh>