Считаем результат: chisl/znam.




Сложение – команда ADD

Инструкция ADD выполняет сложение двух операндов. ADD можно «скармливать» числа со знаком и без (такова специфика дополнительного кода). Обязательным правилом является равность операндов по размеру, между собой можно складывать только два 16-битных числа или два 8-битных.

В первый операнд (приемник) будет помещен результат операции сложения. Многие инструкции придерживаются этого правила.

Работа этой инструкции изменяет флаги процессора. В силу того, что результат может выйти за диапазон приемника (переполнение), стать отрицательным, равным нулю и т.д. поведение флагов позволяет следить за результатом выполнения программы. Интерпретация значения флагов во много зависит от того, воспринимает ли программа операнды как числа со знаком или без:

¾ Флаг CF становится равным единице, если складываемые операнды являются знаковыми и результат вышел за пределы приемника и случился перенос из старшего разряда. CF = 1 при сложении беззнаковых операндов указывает на переполнение и некорректный результат.

¾ Флаг OF = 1 говорит, что произошло переполнение при сложении чисел со знаком.

¾ Флаг SF имеет смысл только для операндов со знаком. SF = 1 если результат отрицательный, и SF = 0, если результат положительный. В случае с беззнаковыми операндами он просто получает значение старшего бита приемника.

¾ Флаг ZF = 1 указывает, что результат равен нулю.

¾ Флаг PF указывает на бинарную четность результата. Это означает что двоичное представление результата содержит четное количество единиц и нулей. Например: 0010111b.

Вычитание – команда SUB

Инструкция SUB выполняет вычитание операндов. Как и в случае с инструкцией ADD результат операции помещается в первый операнд (приемник). Аналогично изменяются флаги процессора.

На самом деле процессор не умеет вычитать числа. Он все делает через сложение Просто перед сложением он подменяет знак второго операнда на противоположный. Так что между инструкциями SUB и ADD даже больше общего.

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

Переполнения

Опасайтесь переполнений в арифметических операциях. Один байт содержит знаковый бит и семь бит данных, т.е. значения от -128 до +127. Результат арифметической операции может легко превзойти емкость однобайтового регистра. Например, результат сложения в регистре AL, превышающий его емкость, автоматически не переходит в регистр AH. Предположим, что регистр AL содержит шест.60, тогда результат команды Add al,20H генерирует AL сумму - шест.80. Но операция также устанавливает флаг переполнения и знаковый флаг в состояние "отрицательно". Причина заключается в том, что шест.80 или двоичное 1000 0000 является отрицательным числом. Т.е. в результате, вместо +128, мы получим -128. Так как регистр AL слишком мал для такой операции и следует воспользоваться регистром AX. Но полное слово имеет также ограничение: один знаковый бит и 15 бит данных, что соответствует значениям от -32768 до +32767.


Умножение

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

"Байт на байт". Один из множителей находится в регистре AL, а другой в байте памяти или в однобайтовом регистре. После умножения произведение находится в регистре AX. Операция игнорирует и стирает любые данные, которые находились в регистре AH.

"Слово на слово". Один из множителей находится в регистре AX, а другой – в слове памяти или в регистре. После умножения произведение находится в двойном слове, для которого требуется два регистра: старшая (левая) часть произведения находится в регистре DX, а младшая (правая) часть в регистре AX. Операция игнорирует и стирает любые данные, которые находились в регистре DX.

В единственном операнде команд MUL и IMUL указывается множитель.

Рассмотрим следующую команду:

mul multr

Если поле MULTR определено как байт (DB), то операция предполагаетумножение содержимого AL на значение байта из поля MULTR. Если поле MULTR определено как слово (DW), то операция предполагает умножение содержимого AX на значение слова из поля MULTR. Если множитель находится в регистре, то длина регистра определяет тип операции, как это показано ниже:

Mul cl; Байт-множитель: множимое в AL, произведение в AX

Mul bx; Слово- множитель: множимое в AX, произведение в DX:AX

Деление

Операция деления для беззнаковых данных выполняется командой DIV, a для знаковых - IDIV. Ответственность за подбор подходящей команды лежит на программисте. Существуют две основные операции деления:

Деление "слова на байт". Делимое находится в регистре AX, а делитель - в байте памяти или в однобайтовом регистре. После деления остаток получается в регистре AH, а частное - в AL. Так как однобайтовое частное очень мало (максимально+255 (шест.FF) для беззнакового деления и +127 (шест.7F) для знакового), то данная операция имеет ограниченное использование.

Деление "двойного слова на слово". Делимое находится в регистровой паре DX:AX, а делитель - в слове памяти или в регистре. После деления остаток получается в регистре DX, а частное в регистре AX. Частное в одномслове допускает максимальное значение +32767 (шест.FFFF) для беззнакового деления и +16383 (шест.7FFF) для знакового.

В единственном операнде команд DIV и IDIV указывается делитель. Рассмотрим следующую команду:

div divisor

Если поле DIVISOR определено как байт (DB), то операцияпредполагает деление слова на байт. Если поле DIVISOR определено как слово (DW), то операция предполагает деление двойного слова на слово.

Выполнение работы:

В ходе данной лабораторной работы нам нужно написать программу, которая бы высчитывала значение уравнения: (A*B)/(4+D) с учетом вводимых пользователем значений.

На прошлой лабораторной работе мы уже начали писать код этой программы и смогли реализовать считывание данных. Подставим теперь вводимые данные в наше уравнение и допишем вывод полученных значений.

Считаем числитель: a * b.

sub al, 48;откуда взялось 48 написано выше

mov bl, namefldB;положили значение B в bl

sub bl, 48

cbw;расширили регистр al до полного регистра ax

mulbl;умножаем ax на bl

addax, 48;переводим число в ASCII формат

movchisl, ax;кладем получившееся число в переменную chisl

mov chisl + 8, '$';конец строки

;Здесь мы добавляем '$', так как изначально переменная chisl имеет текстовый формат. Без данного символа, данные не будут выводиться

lea dx, showchisl;выводит сообщение «Chisl =» на экран mov ah, 09

int 21h

lea dx, chisl;выводит значение числителя на экран int 21h

lea dx, otst;создает отступ в конце строки

int 21h

Рисунок 1 – Листинг кода

Считаем знаменатель: 4 + d.

mov ah, 0;обнуляем ah

moval, namefldD;положилиnamefldDвal

sub al, 48;пересчитали значение с учетом ASCII таблицы

mov bl, 4;положили в bl 4

add al, bl;сложили bl и al

add al, 48;пересчитали значение с учетом ASCII таблицы

mov znam, al;положили полученное значение в znam

lea dx, showznam;выводит сообщение «Znam =» на экран

mov ah, 09

int 21h

lea dx, znam;выводит значение знаменателя на экран

int 21h

lea dx, otst;создает отступ в конце строки

int 21h

 

Рисунок 2 – Листинг кода

Считаем результат: chisl/znam.

mov ax, chisl;загружаем числитель

10

sub ax, 48

mov bl, znam;загружаем знаменатель

sub bl, 48

div bl;делим на bl

add al, 48

mov result, al

lea dx, showresult;выводитсообщение «Result =» наэкран

mov ah, 09

int 21h

lea dx, result

int 21h

lea dx, otst

int 21h

mov ah, 4ch

int 21h

CODE ENDS

END

Рисунок 3 – Листинг кода

В результате у нас получился рабочий код.

Данный код работает только с однозначными числами. То есть и в числителе, и в знаменателе, после выполнения операций, должно получиться однозначное число.

После создания программы переходим в командную строку DOSBox и при помощи команды “tasm <имя файла>” проверяем его на наличие ошибок. Затем пишем команду “tlink <имя файла>”, чтобы еще раз убедиться в корректности. И наконец вводим название файла для его запуска. Программа успешно запустилась и просит ввести значения переменных, а после выдает результат выражения.

Рисунок 4 – Проверка ошибок и выполнение программы

Вывод:

Входелабораторной работы я приобрел навыки использованияарифметических команд при программирования на языке ассемблера. Также я приобретел навыки использования логических команд при программировании на языке ассемблера.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-12-31 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: