Смекни!
smekni.com

Разработка виртуальных лабораторных работ средствами эмулятора Emu8086 (стр. 13 из 21)

. model tiny ; модель памяти, в которой сегменты кода, данных и стека объединены.
. code ; сегмент кода, который содержит и данные.
org 100h ; начало СОМ-файла
begin: ; метка начала кода программы
mov cx,10 ; загружаем в (регистр-счетчик) CX количество повторов (отсчет будет идти от 10 до 0)
Label1: ; создаем метку (Label - метка).
mov ah,9 ; помещаем номер функции DOS "вывод строки (9)" в регистр АН.
mov dx,offset String помещает в регистр DX смещение метки String относительно начала сегмента данных
int 21h ; функция DOS "вывод строки"
loop Label1 ; оператор loop уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label1 (строка 6)
ret ; функция DOS "завершить программу"
string db 'privet $' ; cтрока с содержащая выводимые данные.
end begin ; метка окончания кода программы

В строке (5) загружаем в CX количество повторов (отсчет будет идти от 10 до 0). В строке (6) создаем метку (Label - метка). Далее (строки (7) - (9)) выводим сообщение. И в строке (10) оператор loop уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label1 (строка (6)). Таким образом, строка будет выведена на экран десять раз. Когда программа перейдет на строку (11), регистр CX будет равен нулю.

Организация цикла с помощью команды JMP (Второй способ).

Команда jmp передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда не воздействует на флаги процессора.

Команда jmp имеет пять разновидностей:

переход прямой короткий (в пределах - 128... + 127 байтов);

переход прямой ближний (в пределах текущего программного сегмента);

переход прямой дальний (в другой программный сегмент);

переход косвенный ближний;

переход косвенный дальний.

Все разновидности переходов имеют одну и ту же мнемонику jmp, хотя и различающиеся коды операций. Во многих случаях транслятор может определить вид перехода по контексту, в тех же случаях, когда это невозможно, следует использовать атрибутные операторы (short - прямой короткий переход; near ptr - прямой ближний переход; far ptr - прямой дальний переход; word ptr - косвенный ближний переход; dword ptr - косвенный дальний переход).

Команда Назначение Процессор
JMP метка Безусловный переход 8086
. model tiny ; модель памяти, в которой сегменты кода, данных и стека объединены.
. code ; сегмент кода, который содержит данные.
org 100h ; начало СОМ-файла
begin: ; метка начала кода программы
label1: ; создаем метку
mov ah,9 ; помещаем номер функции DOS "вывод строки (9)" в регистр АН.
mov dx,offset String помещает в регистр DX смещение метки String относительно начала сегмента данных
int 21h ; функция DOS "вывод строки"
jmp Label1 ; переход на строку с меткой Label1
add cx,12 ; прибавить к значению регистра cx число 12 (данная команда не выполняется)
dec cx ; уменьшить значение регистра cx на 1 (данная команда не выполняется)
ret ; функция DOS "завершить программу"
string db "PRIVET",13,10,'$' ; cтрока с содержащая выводимые данные.
end begin ; метка окончания кода программы

В результате работы программы будет зациклен блок строк (6) - (10) (Вывод строки PRIVET многочисленное количество раз) Строки (10) - (11).

Организация цикла с помощью команд DEC и JNZ (Третий способ).

С помощь этих операторов можно создавать циклы, которые будут работать быстрее оператора Loop. Комбинированная работа команд DEC и JNZ уменьшает содержимое регистра CX на 1 и выполняет переход на метку, если в CX не равен нулю.

Команда DEC, кроме того, устанавливает флаг нуля во флаговом регистре в состояние 0 или 1. Команда JNZ затем проверяет эту установку.

Аналогично командам JMP и LOOP операнд в команде JNZ содержит значение расстояния между концом команды JNZ и адресом перехода (Label1), которое прибавляется к командному указателю. Это расстояние должно быть в пределах от - 128 до +127 байт.

Следующий пример будет работать так же, как и Пример №1.1, только быстрее.

. model tiny ; модель памяти, в которой сегменты кода, данных и стека объединены.
. code ; сегмент кода, который содержит данные.
org 100h ; начало СОМ-файла
begin: ; метка начала кода программы
mov cx,10 ; загружаем в (регистр-счетчик) CX количество повторов (отсчет будет идти от 10 до 0)
Label1: ; создаем метку (Label - метка).
mov ah,9 ; помещаем номер функции DOS "вывод строки (9)" в регистр АН.
mov dx,offset String помещает в регистр DX смещение метки String относительно начала сегмента данных
int 21h ; функция DOS "вывод строки"
dec cx ; оператор DEC уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label1
jnz Label1 ; условный переход на строку с меткой Label1
ret ; функция DOS "завершить программу"
string db 'priver ',13,10, '$' ; cтрока с содержащая выводимые данные
end begin ; метка окончания кода программы

2. Программа для практики.

Напишем программу, выводящую на экран все ASCII-символы (16 строк по 16 символов в строке).

. model tiny ; модель памяти в которой сегменты кода, данных и стека объединены.
. code ; сегмент кода, который содержит данные.
org 100h ; начало СОМ-файла
begin: ; метка начала кода программы
mov cx,256 ; задаем значение счетчика (256 символов)
mov dl,0 ; первый символ - с кодом 00
mov ah,2 ; номер функции DOS "вывод символа"
cloop: int 21h ; вызов DOS
inc dl ; увеличение DL на 1 - следующий символ
test dl,0Fh ; если DL не кратен 16
jnz continue_loop; ; продолжить цикл,
push dx ; иначе: сохранить текущий символ
mov dl,0Dh ; вывести CR
int 21h ; вызов DOS
mov dl,0Ah ; вывести LF
int 21h ; вызов DOS
pop dx ; восстановить текущий символ
continue_loop: ; метка
loop cloop ; продолжить цикл
ret ; завершение СОМ-файла
end begin ; метка окончания кода программы

Здесь с помощью команды LOOP оформляется цикл, выполняющийся 256 раз (значение регистра СХ в начале цикла). Регистр DL содержит код символа, который равен нулю в начале цикла и увеличивается каждый раз на 1 командой INC DL. Если значение DL сразу после увеличения на 1 кратно 16, оно временно сохраняется в стеке и на экран выводятся символы CR и LF, выполняющие переход на начало новой строки. Проверка выполняется командой TEST DL,0Fh - результат операции AND над DL и 0Fh будет нулем, только если младшие четыре бита DL равны нулю, что и соответствует кратности шестнадцати.

3. Содержание отчета.

3.1 Титульный лист.

3.2 Индивидуальный вариант задания.

3.3 Тестовые наборы данных и предполагаемые результаты.

3.4 Текст программы до отладки.

3.5 Список ошибок, обнаруженных при отладке.

3.6. Результаты выполнения тестов.

3.7. Распечатка листинга компиляции отлаженной программы с указанием работы каждой строки.

4. Задание для выполнения.

4.1 Выполните все примеры, что содержатся в описании данной лабораторной работы.

4.2 Проанализируйте работу программы примера для практики.

4.3 Изучить условия организации циклических переходов на языке Ассемблера.

4.4 Напишите программу, выводящую на экран слово "!!!!!!!!!! Hello!!!!!!!!!!" используя команды циклических переходов (3 варианта).

4.5 Получите задание у преподавателя (один из пяти вариантов табл. №1) и, пользуясь правилами оформления ассемблерных программ, создайте программу, выводящую на экран слово, D число раз.

4.6 Программу ассемблируйте в файл типа *.com или *. exe (на выбор);

5. Контрольные вопросы

5.1 Организация цикла с помощью команды loop?

5.2 Значимость регистра cx?

5.3 Максимальное число повторений команд цикла определяемого регистром сх?

5.4 Организация цикла с помощью команды jmp?

5.5. Разновидности команды jmp?

5.6. Организация цикла с помощью команд dec и jnz?

Табл. №1

№ вар. Выводимые данные Формула расчета А B С
Циклический переход D=A+B+C 101 345 121
Hello world D=A-B+C 578 152 149
Good Bye D=A+B-C 333 223 16
Группа D=A-B+C 1502 834 1
Лабораторная работа D=A-B-C 1056 33 125

ЛАБОРАТОРНАЯ РАБОТА №9

СПОСОБЫ И МЕТОДЫ ВЫВОДА ЧИСЕЛ

Цель работы: Освоить методы вывода чисел в двоичном, шестнадцатеричном и десятичном коде.

1. Вывод двоичного кода числа, записанного в регистр DH.

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

Нужно последовательно проанализировать биты числа. В данной работе ограничимся байтом, который будем хранить в DH. Если бит нулевой (сброшен), то нужно вывести '0', если установлен, то '1'.