Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_АСС.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
404.99 Кб
Скачать

2.2. Команда безусловного перехода

Безусловный переход в программе на ассемблере производится по команде JMP. Полный формат команды следующий:

JMP [модификатор] адрес_перехода.

Адрес_перехода может быть либо меткой, либо адресом области памяти, в которую предварительно помещен указатель перехода.

В системе команд микропроцессора существуют несколько кодов машинных команд безусловного перехода. Их различия определяются дальностью перехода и способом задания целевого адреса. Дальность перехода определяется местоположением операнда адрес_перехода. Этот адрес может находиться в текущем сегменте кода или в некотором другом сегменте. В первом случае переход называется внутрисегментным или близким, а во втором случае – межсегментным или дальним. Ограничимся рассмотрением внутрисегментных переходов.

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

Прямой короткий внутрисегментный переход применяется, когда расстояние от команды JMP до адреса перехода не более чем 127 байтов выше или ниже. В этом случае транслятор языка формирует машинную команду безусловного перехода длиной 2 байта: первый байт – код операции, второй байт – смещение. В коде операции заложена информация о том, что второй байт интерпретируется как смещение. Здесь нужно отметить одну особенность большинства трансляторов ассемблера – они являются однопроходными, иными словами, машинный код программы получается за один просмотр команд от начала программы до ее окончания. В связи с этим обстоятельством, если безусловный переход должен происходить на адрес до команды JMP, то транслятор может легко вычислить смещение. Если же переход короткий, но на метку после команды JMP, то транслятору нужно подсказать, что он должен сформировать команду безусловного короткого перехода. С этой целью в команде JMP используется модификатор SHORT PTR (полностью - SHORT POINTER или короткий указатель):

JMP SHORT PTR M1

. . . . . . не более 35-40 команд

M1: MOV AL, 34H.

Прямой внутрисегментный переход отличается от короткого тем, что длина машинной команды составляет 3 байта, в которой два последних байта интерпретируются как смещение. Нетрудно определить, что в этом варианте можно осуществлять переход в пределах 64 Кбайт памяти относительно следующей за JMP команды.

Косвенный внутрисегментный переход означает, что в команде JMP указывается не сам адрес перехода, а место, где этот адрес записан. Например:

LEA BX, M1

JMP BX

. . . . . .

M1: MOV AL, 34H

Или

DSEG SEGMENT PARA PUBLIC ‘DATA’

ADDR DW M1

. . . . . . . .

CSEG SEGMENT PARA PUBLIC ‘CODE’

ASSUME CS:CSEG, DS:DSEG, SS:STACK

. . . . . .

JMP ADDR.

В командах косвенного перехода рекомендуется применять модификатор NEAR, т.к. при косвенном переходе не всегда транслятору удается определить, находится адрес перехода в текущем сегменте кода или нет.

3. Методика выполнения работы

Программирование на Ассемблере имеет много общего с программированием на языке высокого уровня, однако есть и существенные особенности, главная из которых гласит: программирование на языках низкого уровня требует большей степени детализации алгоритма. Основные рекомендации проектирования Ассемблер-программ:

- четко сформулируйте задачу, которую должна решать создаваемая программа. Чаще всего для этого необходимо выделить из задачи более простые подзадачи, в которых алгоритм преобразования информации прост и понятен для реализации;

- разработайте схему программы в терминах действий (смысловых операций обработки). В качестве комментариев к разработанной схеме могут быть описаны основные механизмы реализации программы;

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

- для более простой реализации на языках низкого уровня рекомендуется все блоки схемы программы помещать последовательно “в столбик”, от терминатора “начало” до терминатора “конец”. От блоков “решение” один выход должен идти к следующему блоку, а второй – к блоку выше или ниже в последовательности. Такое построение схем программ позволит при реализации сразу определять, где должны проставляться метки: если к блоку подходит более одной линии, первая команда такого блока должна быть помечена;

- используйте другие программы в качестве примеров. Несколько начальных и конечных команд во всех программах на языке ассемблера совершенно одинаковы. Используйте таблицы команд, приведенные в приложении В;

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

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

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

Прежде чем приступить к разработке схемы и программы, определим, какие исходные данные и переменные требуются для программы обработки. Это должны быть заданная строка символов, переменные FIRST и LAST, размер которых должен совпадать с размером символа в символьной строке, и счетчик количества символов, лежащих в заданном интервале, пусть это будет SCH. Уяснив состав переменных, можем определить сегмент данных следующим образом:

DSEG SEGMENT PARA PUBLIC ‘DATA’

STR DB8RFJM/96QZDLE[]X ;заданная символьная строка

Len_str=$-str ;определяем длину строки

FIRST DB ( ) ; первый символ из диапазона

LAST DB ( ) ; последний символ из диапазона

SCH DB (0) ; количество символов из диапазона

FLAG DB (0) ; FLAG=1флаг установлен

DSEG ENDS

Схема программы с комментариями в виде команд программы приведена на рис. 3.

CSEG SEGMENT PARA PUBLIC ‘CODE’

ASSUME CS:CSEG, DS:DSEG, SS:STACK

Установить указатель на начало строки

OUR_PROG PROC FAR

PUSH DS

SUB AX,AX

PUSH AX

MOV AX,DSEG

MOV DS,AX

ДА XOR SI,SI

CYCL: CMP STR[SI],’C’

JB NEXT

НЕТ

CMP STR[SI],’N’

ДА JA NEXT

НЕТ

НЕТ TEST FLAG,1

JE M

ДА

Запомнить символ в FIRST и установить флаг

MOV AL, STR[SI]

MOV FIRST, AL

MOV FLAG,0

Запомнить символ в LAST

M: MOV AL, STR[SI]

MOV LAST, AL

Перейти к следую-щему символу

NEXT: INC SI

CMP SI, LEN_STR

JNE CYCL

RET

OUR_PROG ENDP

CSEG ENDS

НЕТ ДА END OUR_PROG

Рис. 3 – Схема и программа подсчета символов в заданном диапазоне

На рис. 3 в основном все команды записаны напротив соответствующих символов схемы. Исключения составляют команды и символы, соединенные стрелкой.

Ожидаемый результат обработки: FIRST=F, LAST, SCH=6 (FJMDLE). Можете убедиться в правильном функционировании программы, набрав ее текст и просмотрев результаты в отладчике.