Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебн пособ по арх и прогр МП.doc
Скачиваний:
64
Добавлен:
10.12.2013
Размер:
1.59 Mб
Скачать

Тема 12. Циклическая разветвленная программа

12.1.Создание программы.

В завершении обучения программированию на Ассемблере рассмотрим создание типовой по структуре простой циклической и разветвленной программы.

Задано: Массив слов SOURCE располагается в сегменте данных. Переместить массив SOURCE в массив DEST, находящийся в дополнительном сегменте данных причем, если элемент массива равен 0FAh (250), то обнулить его, а иначе просто переместить. Массив содержит 5 элементов.

12.1.1.Составление программы

В любом текстовом редакторе создадим текстовый Asm-файл программы.

1) Определим сегмент стека.

_STACK SEGMENT PARA STACKSTACK’; сегмент стека

DB 32 DUP ('ST'); стек размером 64 байта (32 повторения 2-х

; символов ST по байту каждый)

_STACK ENDS; закроем описание сегмента стека _STACK

2) Определим сегмент данных.

_DATA SEGMENT; сегмент данных

SOURCE DW 10,250,30,40,300; массив слов - источник. Из этого

;массива мы будем брать числа. Массив записан в

; десятичной форме.

_DATA ENDS; закроем описание сегмента данных _DATA

3) Определим дополнительный сегмент данных.

_DOP SEGMENT

DEST DW 5 DUP (?) ; массив слов - приемник. В этот массив мы

; будем записывать элементы. Этот массив пока

; не содержит значений, но место под него

; зарезервировано - 5 слов.

_DOP ENDS

4) Определим сегмент кода.

_CODE SEGMENT PUBLIC ‘CODE’; сегмент кода

OUR_PROG PROC FAR; описываем процедуру

; OUR_PROG

ASSUME CS: _CODE, DS: _DATA, SS: _STACK; ассоциируем имена

;сегментов нашей программы с регистрами.

;помещаем в стек такие начальные значения, чтобы программа

; могла по завершению возвратить управление вызвавшей ее

;программе (например ОС)

PUSH DS; поместить в регистр номер блока адреса возврата

MOV AX, 0; обнулить регистр AX

PUSH AX; поместить в стек нулевое смещение адреса возврата

; инициализируем регистр сегмента данных и дополнительного сегмента

MOV AX, _DATA; через регистр AX

MOV DS, AX; загрузка в DS указателя сегмента данных

MOV AX, _DOP

MOV ES, AX ; загрузка в ES указателя доп. сегмента данных

; загрузим в регистры BX и DI смещения в сегменте данных,

;указывающих на первые элементы массивов SOURCE и DEST

MOV BX, OFFSET SOURCE; загрузка указателей массива SOURCE

;в BX

LEA DI, DEST; загрузка указателей массива DEST в DI

;команды MOV и LEA здесь имеют одно назначение

; загрузим в регистр CX количество проходов цикла, равное

; количеству элементов в нем

MOV CX, 5; счетчик проходов цикла

; организуем цикл

A_1: MOV AX, [BX]; загрузка числа в регистр AX из массива-источника

; по указанному адресу, хранимому в регистре BX

CMP AX, 0FAH; сравнение элемента в регистре AX с константой

JNZ N_EQ; если число не равно (флаг Z не равен 1), то переход

; на метку N_EQ

MOV AX,0 ; иначе (флаг Z равен 1), то обнуляем элемент

; в регистре AX (в случае если флаг Z не равен 1

; эта команда пропускается)

N_EQ: MOV ES: [DI], AX; теперь помещаем обработанный элемент из

; регистра AX (обнуленный, если он был равен константе и

; неизменный, если не равен) в массив-приемник по

; адресу, указанному в массиве DI

ADD DI, 2; увеличиваем адрес указателя массива-приемника

; на 2 байта т.к. слово=2 байта

ADD BX, 2; увеличиваем адрес указателя массива-источника

; на 2 байта т.к. слово=2 байта

LOOP A_1; повторение цикла, пока значение регистра-счетчика CX

; не станет равным 0

RET; команда возврата из процедуры, она извлекает данные,

; которые мы положили в стек в начале программы

OUR_PROG ENDP; закрываем описание процедуры OUR_PROG

_CODE ENDS; закрываем описание сегмента кода _CODE

END OUR_PROG; закрываем описание программы