- •Практическая работа 2 программирование арифметических задач
- •Цель работы
- •Условные обозначения
- •Команда пересылки
- •Команды сложения и вычитания
- •Команды умножения
- •Команды деления
- •Изменение размера числа
- •Оператор указания типа ptr
- •Безусловный переход
- •Команда сравнения
- •Команды условного перехода
- •Пример программы
- •Задания для самостоятельной работы
-
Пример программы
2.12.1 Формулировка задачи
Разработать программу вычисления Z в зависимости от значения символа ch по формуле:
Z
=
55, если ch < 's'
где: v (байт) - возраст студента ( количество полных лет );
d (байт) - день рождения студента.
Значение символа ch вводится с клавиатуры.
При тестировании программы для вывода полученных значений Z использовать модуль IO.ASM [9], листинг которого представлен в приложении А.
2.12.2 Постановка задачи
Для определения типа величины Z проанализируем формулу ее расчета. В первой, наиболее сложной части формулы, Z – результат деления чисел, значит под размещение Z необходимо выделить массив из двух элементов (неполное частное и остаток). Тип обоих результатов деления совпадает с типом делителя, в данном случае, это произведение 2*d, причем d по условию задачи – байт. Произведение сомножителей – байтов дает результат размером слово. Таким образом, Z следует описать как массив из двух элементов-слов.
В начале программы нужно предусмотреть вывод приглашения на ввод любого ASCII-символа. Для ввода символа использовать возможности прерывания int 21h, причем для контроля за правильностью ввода использовать функцию 1h, дающую «эхо».
После сравнения введенного символа с заданным выполнить расчет Z по соответствующей формуле и перейти на блок вывода результата.
Блок вывода должен обеспечивать вывод двух результатов, если расчет выполняется по первой части формулы, и одного – если по второй. Для корректной работы блока вывода ввести вспомогательную переменную - флаг, имеющую некоторое начальное значение (например,0), задаваемое при ее описании, и изменяющуюся (например, на 1), если расчет выполняется по первой части формулы. Блок в обоих случаях обеспечивает безусловный вывод одного результата (неполного частного или 55), а далее после анализа флага либо выводит второй результат (остаток), либо сразу выполняет переход на завершение программы. Перед выводом остатка предусмотреть табуляцию – перевод курсора вправо на 8 позиций.
При выполнении расчета по первой части формулы в целях сокращения пересылок данных при делении сначала подсчитать знаменатель 2*d, а потом числитель 3*v.
Учесть, что делитель имеет тип – слово, следовательно, делимое (числитель) размещается в двойном слове DX:AX. В то же время фактически числителю, который является результатом умножения байтов 3*v, хватает слова, а именно, АХ. Значит в этом конкретном случае для получения правильного результата перед делением необходимо очистить регистр DX.
Для вывода чисел подключить к программе модуль IO.ASM.
2.12.3 Тестирование программы
Исходные данные: d=28, v=20.
При вводе символа f расчет производится по первой части формулы, неполное частное равно 1 , а остаток 4.
Если ввести символ t, то результат равен 55.
2.12.4 Листинг программы
model small
include io.asm ; подключение модуля io.asm
.stack 100h
.data
d db 28
v db 20
z dw ?, ? ; для результата
priglash db 'Введите символ-> ','$'
rez db 'Результат расчета -> ','$'
flag db 0 ;начальное значение флага
.code
start: ; точка входа в программу
mov ax, @data ; загрузка адреса сегмента данных
mov ds, ax
mov dx, offset priglash ; вывод строки
mov ah, 9h
int 21h
mov ah, 1h ; ввод символа
int 21h ; код символа в al
cmp al, 's' ; сравнение кодов символов
jb menshe ; если введенный символ меньше, на menshe
;********* ch≥s' - расчет по первой части формулы *********
mov flag, 1 ; новое значение флага =1
mov al, 2 ; подготовка к умножению (знаменатель)
mul d ; [ax]:=2d
mov bx, ax ; копирование 2d в bx
mov al, 3 ; числитель
mul v ; [ax]:=3v
; для деления числитель должен быть: в dx - старшее слово,
; в ax - младшее слово (уже находится)
mov dx, 0 ; очистка dx
div bx ; неполное частное в ax, остаток в dx
mov z, ax ; неполное частное в первое слово массива z
mov z+2, dx ; остаток во второе слово массива z
jmp vivod ; безусловный переход на блок вывода
; ************* расчет по второй части формулы ***************
menshe: mov z, 55 ; результат в первое слово массива z
; ******************** блок вывода ************************
vivod: mov dx, offset rez ; вывод строки - сообщения
mov ah, 9h
int 21h
outint z ; вывод первого слова массива z
cmp flag, 0 ; если флаг=0, вывод завершен
je finish
; флаг изменился, продолжение вывода
mov dl, 9 ; вывод символа «табуляция»
mov ah, 2h
int 21h
outint z+2 ; вывод второго слова массива z
; завершение работы
finish: mov ah, 1 ; задержка для обозрения результата
int 21h
mov ax, 4C00h
int 21h
end start