Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Gazu1Z3ovv.file.doc
Скачиваний:
1
Добавлен:
30.04.2022
Размер:
232.45 Кб
Скачать

2.6. Работа с циклами и массивами

Организация циклов

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

а) if X>0 then S1 else S2

б) while X>0 do S

в) repeat S until X>0

где S, S1 и S2 – некоторые операторы, а X – знаковая переменная, реализуются по схемам, приведенным в табл. 8.

Таблица 8

Варианты реализации ветвлений и циклов с неизвестным числом повторений в ассемблере

if X>0 then S1 else S2

while X>0 do S

repeat S until X>0

CMP X, 0

JLE L1

JMP L2

L 1:

L2:

BEG: CMP X, 0

JLE FIN

JMP BEG

FIN: ………….

B EG:

CMP X, 0

JG BEG

Для реализации цикла с известным числом повторений можно воспользоваться командой LOOP записываемой следующим образом:

LOOP <метка>

Действие этой команды можно записать следующим образом (пользуясь операторами языка Паскаль):

CX:=CX–1 ; уменьшение счетчика повторений цикла

; на единицу (предварительно число повторений

; цикла надо записать в CX)

IF CX<>0 THEN GOTO <метка> ;

С помощью команды LOOP цикл, который необходимо повторить N раз можно записать следующим образом:

MOV CX, N ; в CX записывается число

; повторений цикла N (обязательно N>0)

L: ; начало цикла

… ; тело цикла

LOOP L

Данная команда обладает рядом особенностей:

1) В качестве счетчика цикла обязательно должен использоваться регистр CX.

2) Начальное значение для CX должно быть присвоено до цикла, причем данному регистру надо присваивать ровно столько, сколько раз должен повториться цикл.

3) Так как команда LOOP ставится в конце цикла, тело цикла выполниться хотя бы один раз. Поэтому для того, чтобы предусмотреть вариант нулевого повторения цикла, необходимо сделать обход цикла:

MOV CX, N ; N>=0

JCXZ L1 ;CX=0 -> L1

L: …

… ;

LOOP L

L1: …

Именно для осуществления подобных обходов и была введена команда условного перехода JCXZ.

Работа с массивами

Нумерация элементов массива

Пусть имеется массив X из 30 элементов слов.

X DW 30 DUP (?)

При описании массива указывается количество элементов в нем и их тип, но не указывается, как нумеруются его элементы. Обычно считается, что элементы массива нумеруются с 0, чтобы наиболее удобно считать адрес очередного элемента массива. Если первый элемент массива имеет номер 0, то адрес i-го элемента массива можно определить следующим образом:

Адрес (X[i]) =X + (type X)*i

где type X – размер элемента массива в байтах (для слова type X = 2, для двойного слова type X = 4).

Модификация адресов

Для реализации обращения к разным элементам массива в одной и той же команде цикла необходимо использовать модификацию адресов.

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

MOV CX, A[BX]

Данная команда будет работать не с указанным в ней адресом A, а с исполнительным адресом, который вычисляется по формуле:

Аисп = (A + [BX]) mod 216

Таким образом, прежде чем выполнить команду, центральный процессор прибавит к адресу A текущее содержимое регистра BX, получит некоторый новый адрес и именно из ячейки с этим адресом возьмет второй операнд. Если в результате сложения получилась слишком большая сумма, то от нее берутся только последние 16 битов, на что указывает операция mod в приведенной формуле.

Замена адреса из команды на исполнительный адрес называется модификацией адреса, а регистр, участвующий в модификации, называют регистром-модификатором или просто модификатором. В качестве модификатора можно использовать только регистры BX, BP, SI или DI.

Индексирование

Пример. Пусть имеется массив

X DW 100 DUP (?) ; X[0..99]

Требуется записать в регистр AX сумму элементов массива.

Для нахождения суммы надо сначала в AX записать 0, а затем в цикле выполнить операцию AX:=AX+X[i] при i от 0 до 99. Команда, соответствующая этой операции должна быть следующей:

ADD AX, X + 2 * i

Но данная команда недопустима правилами языка ассемблер: все части команды, в том числе и адрес должны быть фиксированными. Здесь же адрес меняется вместе с изменением индекса i.

Решить проблему поможет разбиение переменного адреса X+2*I на два слагаемых – постоянное слагаемое X, которое не зависит от индекса i, и на переменное слагаемое 2*i, зависящее от индекса. Постоянное слагаемое записывается в саму команду, а переменное слагаемое заносится в регистр-модификатор (например, в SI), название которого записывается в команду.

Так как регистр-модификатор все время один и тот же, то команда будет иметь фиксированный вид, т.е. удовлетворять правилам машинного языка. С другой стороны, меняя содержимое регистра SI в другой команде, можно заставить неменяющуюся команду работать с разными адресами и, тем самым, корректно реализовать алгоритм.

При такой реализации задачи важно правильно менять содержимое регистра SI. Сначала в SI необходимо записать 0, а затем увеличивать его значение с шагом 2; в результате команда будет работать с адресами X, X+2, X+4, …, X+198.

Таким образом, фрагмент программы нахождения суммы элементов массива X может выглядеть следующим образом:

MOV AX, 0 ; начальное значение суммы

MOV СX, 100 ; счетчик цикла

MOV SI, 0 ; начальное смещение по вектору

; (индекс)

L: ADD AX, X [SI] ; AX := AX + X[i]

ADD SI, 2 ; следующий индекс

LOOP L ; цикл 100 раз

Задание 5. Написать фрагмент программы на ассемблере (описание переменных и команды вычислений) в соответствии с указанным вариантом. Использовать операторы организации цикла и индексирование.

1. Найти первый положительный элемент массива из 8 целых со знаком типа слово.

2. Найти (поместить в специально отведенную ячейку памяти) меньший из элементов массива из 9 целых со знаком типа байт.

3. Найти последний отрицательный элемент массива из 10 целых со знаком типа слово.

4. Поменять местами соседние (первый со вторым, третий с четвертым и т.д.) элементы массива 10 целых без знака типа байт.

5. В последовательные 10 байт памяти поместить коды букв от ‘A’ до ‘J’. Выполнить размещение не в директиве описания данных, а программно.

6. Найти сумму двух векторов целых размером в слово (сформировать третий вектор). Здесь вектор – одномерный массив.

7. Вычислить сумму двух двойных слов (считать, что в них хранятся беззнаковые числа). Сумму разместить в третьем двойном слове. Если сумма не помещается в двойном слове, то перейти на метку error.

8. Проверить, упорядочен ли по возрастанию массив из 10 целых без знака типа байт.

9. Проверить, упорядочен ли по убыванию массив из 12 целых со знаком типа слово.

10. Найти (поместить в регистр BX) больший из элементов массива из 10 беззнаковых целых типа слово.

Рекомендуемая литература:

Пильщиков. Глава 4. «Переходы. Циклы». До параграфа 4.4. «Вспомогательные операции ввода-вывода».

БИБЛИОГРАФИЧЕСКИЙ СПИСОК

1. Операционные системы: учеб. пособие / Н.И. Гундорова, М.Ю. Сергеев. Воронеж: ГОУВПО «Воронежский государственный технический университет», 2011. 156 с.

2. Пильщиков В.Н. Программирование на языке ассемблера IBM PC / В.Н. Пильщиков. М.: «Диалог-МИФИ», 1994. 288 с.

3. Гордеев А.В. Операционные системы: учебник для вузов. /А.В. Гордеев. 2-е изд. СПб.: Питер, 2009. 416 с.

4. Танненбаум Э. Современные операционные системы. / Э. Танненбаум. 2-е изд. СПб.: Питер, 2007. 1038 с.

СОДЕРЖАНИЕ

1. Введение в теорию ОС……….……………………………

1

1.1. Указания к выполнению работы ………………........

1

1.2. Учебные темы и вопросы …………………………...

2

2. Введение в программирование на ассемблере…………..

6

2.1. Указания к выполнению работы ……………….......

6

2.2. Представление целых в памяти ПК ………………..

8

2.3. Ассемблер: начальные сведения. Директивы

описания данных и команды пересылок ………….……

9

2.4. Команды сложения и вычитания ……………...……

14

2.5. Команды условного и безусловного перехода…....

15

2.6. Работа с циклами и массивами……………………...

21

Библиографический список…………………………………

27

30

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]