Помощь в написании студенческих работ
Антистрессовый сервис

Разработка алгоритма и программы на ассемблере

КурсоваяПомощь в написанииУзнать стоимостьмоей работы

В блоках 1.13−1.22 выполняется деление числа в переменной tmp4 (сумма x1 и x2) на число в tmp3 (произведение 25 и x1), результат записывается в tmp1: в блоке 1.13 обнуляются переменные частного tmp1 и остатка tmp2, в регистр С загружается количество бит в делимом (40) и сбрасывается признак переноса, далее идет цикл деления (блоки 1.14−1.22): делимое сдвигается влево (блок 1.14), остаток… Читать ещё >

Разработка алгоритма и программы на ассемблере (реферат, курсовая, диплом, контрольная)

Для полноценного функционирования электронного средства существует необходимость в решение различных не сложных арифметических и логических функций, но огромное количество таких задач представляет собой очень трудоемкий и длительный процесс и его целесообразно выполнять с помощью микропроцессорной техники. Решению одной из таких задач посвящена данная курсовая работа. В которой будет разработана программа по вычислению функции на языке программирования ассемблер для микропроцессора Кр580ВМ80.

В ходе решения данной задачи нам необходимо подробно изучить микропроцессорную технику на примере однокристальной микро-ЭВМ Кр580ВМ80. Освоить приёмы программирования на языке низкого уровня — ассемблер. Затем произвести детальный анализ технического задания и найти пути решения в виде наиболее привлекательного с точки зрения рациональности алгоритма программы. Составить всю необходимую документацию к данной программе.

1. Анализ технического задания

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

Исходные данные

1. Функция ;

2. Тип микропроцессора КР580ВМ80;

3. Рабочая частота — 2 МГц;

4. Исходные числа целые, положительные, 4-х байтовые, двоичные;

5. Специальное требование — минимизировать объем памяти программы.

Рассмотрим основные ресурсы с точки зрения программирования, которые предоставляют МП КР580ВМ80. Данный МП представляет собой однокристальный 8-разрядный микропроцессор и включает в себя три основные части: АЛУ, банк регистров, схему управления. Взаимосвязь между различными блоками осуществляется с помощью внутренней 8-разрядной шины данных. МП имеет внешнюю 8-и разрядную, двунаправленную шину данных с тремя логическими состояниями и 16-разрядную однонаправленную шину адреса с тремя логическими состояниями.

Такая 16-разрядная шина адреса позволяет адресовать 216 = 65 536 ячеек памяти.

АЛУ МП представляет собой 8-разрядное комбинационное логическое устройство, предназначенное для выполнения арифметических и логических операций. Один из операндов, поступающих на АЛУ, всегда размещается в аккумуляторе, в аккумулятор помещается и результат операции. АЛУ данного МП выполняет только простейшие операции (сложение, вычитание, сдвиг и.т.д.), более сложные операции реализуются программно.

Все регистры МП Кр580ВМ80 можно разделить по назначению на две группы: регистры общего назначения (РОН) и специальные регистры.

МП имеет 8 регистров общего назначения. Из них регистры W и Z программно недоступны и предназначены для внутренних пересылок информации в МП, в частности для хранения двух и трехбайтовых команд. Регистры В, С, D, E, Н, L программно доступны и предназначены для хранения операндов и промежуточных результатов вычислений. Использование этих регистров в программе позволяет сократить время выполнения программы и её объём. Эти регистры могут использоваться как отдельно (как 8-разрядные регистры), так и в парах НL, BC, DE, при этом они используются для хранения 16-разрядных операндов и адресов. Пара регистров НL может использоваться для хранения адреса ячейки памяти (М) при обращении к ней как к регистру.

К специальным регистрам относятся: счетчик команд, указатель стека, регистр адреса, аккумулятор, регистр признаков.

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

Счетчик команд Рс представляет собой 16-ти разрядный регистр, содержащий адрес выполняемой команды.

Указатель стека Sр — 16-разрядный регистр, предназначенный для хранения адреса вершины стека. Стек располагается в оперативной памяти. Поэтому при разбивке адресного пространства необходимо в ОЗУ выделить область для стека.

Регистр состояния (регистр признаков) предназначен для хранения информации о результате операции.

Также МП содержит схема десятичной коррекции предназначена для автоматической коррекции результата операции сложения при представлении операндов, в двоично-десятичном коде.

Система команд МП включает команды пересылки, инкремента и декремента, команды арифметических и логических операций, сдвига, передачи управления, ввода-вывода и несколько дополнительных команд.

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

По заданию входными числами х1, х2, являются целые, положительные, 4-х байтные, двоичные числа. 4-х байтное двоичное число может принимать значения от 0 до 232−1 (FFFFFFFF16).

Максимальное значения функция достигает при минимальном значении знаменателя, то есть при х1=1 и равно (1+232−1+232−1)/(41) =2 147 483 647 (7FFFFFFF16). Таким образом, для хранения результата в двоичном виде необходимо четыре байта.

Для хранения результата сложения х1, х2 и x необходимо пять байт, так как 232−1+232−1+232−1=12 884 901 885 (2FFFFFFFD16).

Для хранения результата умножения 4 на х1 необходимо также пять байт, так как 4232−1=17 179 869 180 (3FFFFFFFC16).

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

Проанализируем заданную математическую функцию. Она содержит три арифметических действия, поэтому программу можно логически разделить на три составляющих.

В первую очередь следует найти сумму. В своём составе МП Кр580ВМ80 имеет байтовое АЛУ с фиксированным набором команд. В этом перечне присутствует команда сложения. Так как разрядность процессора равна восьми, а переменные состоят из нескольких байт сложение будем производить, побайтно переходя от младшего к старшему с учётом переноса. В начале задаются счетчик сложений кратный количеству байт чисел, начальные адреса, которыми являются ячейки памяти с младшими байтами чисел. Далее происходит непосредственное сложение. После этого необходимо изменить текущие адреса на следующие. Далее модифицируем счётчик, и если он показывает, что необходимое количество сложений произошло, выходим из цикла, в противном случае возвращаемся в блок сложения и повторяем цикл, начиная с него до тех пор, пока счетчик не достигнет определенного значения.

Для вычисления выражения 4 необходимо разработать алгоритм программного умножения. Простейший способ умножения двоичных чисел заключается в суммировании множимого с накоплением, которое производится m раз, где m — значение множителя. Основной недостаток данного способа, почти исключающий его практическое применение, заключается в очень низком быстродействии. Такого недостатка лишен второй алгоритм. Он выполняет умножение сдвигом разрядной сетки. Суть умножения сводится к тому, что один из множителей (второй) всегда должен сдвигаться вправо (сдвиг разрядной сетки вправо). При этом крайний разряд можно будет всегда оценивать на признак: ноль или один. Если он будет равен единице, то в сумму нужно будет добавлять первый множитель. Первый множитель, на каждой итерации цикла тоже должен изменяться, а, именно, его разрядную сетку нужно сдвигать влево. Будет получаться, что мы на каждой итерации добавляем ему справа по нолику. Имеются четыре варианта реализации данного способа, определяемых тем, начиная с каких цифр — младших или старших — анализируется множитель и что сдвигается — множимое или частичная сумма.

Данный алгоритм будет занимать гораздо меньше места, поскольку число раз повторения цикла будет зависеть не от значения числа множителя, а от количества его разрядов. Применение этого алгоритма особенно удобно при больших числах. Подобные программистские «выверты» позволили осуществить такие алгоритмы умножения, при которых задействованы лишь регистры МК, и нет обращений к внутренней или внешней памяти данных. Благодаря этому скорость выполнения умножения достаточно высока, т. к. операции с регистрами гораздо быстрее аналогичных операций с ячейками ОЗУ.

Для деления многобайтных чисел необходимо разработать алгоритм программного деления. Самый простой способ деления заключается в вычитании из делимого делителя, пока делимое не станет меньше делителя, и одновременном увеличении счетчика для нахождения частного. Этот способ не применяется, так как при большом делимом относительно делителя программа выполняется крайне медленно, что не соответствует требованию.

Более эффективный способ реализуется методом «вычитание-сдвиг». Так как частное можно получать, только начиная со старших разрядов, имеются два варианта деления — со сдвигом остатка влево и со сдвигом делителя вправо. Второй вариант на практике не применяется из-за необходимости иметь регистры остатка и делителя удвоенной длины, что сказывается на быстродействии.

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

Таким образом, для вычисления функции необходимо выполнить следующие основные действия (рисунок 1).

Рисунок 1 — Обобщенный алгоритм программы Основываясь на описанных методах умножения и деления, можно разработать программу вычисления заданной функции для микропроцессора КР580ВМ80, которая будет удовлетворять поставленным требованиям.

Рабочая частота микропроцессора. Эти данные предназначены для расчетной части работы, а именно для нахождения времени выполнения программы из расчета, что время одного такта процессора вычисляется по формуле (1.1).

(1.1)

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

2. Разработка алгоритма программы

В анализе ТЗ было указано, что в микропроцессоре КР580ВМ80 отсутствуют команды многобайтного умножения и деления двоичных чисел. Поэтому были рассмотрены и выбраны методы программного вычисления данных операций.

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

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

Рисунок 2 — Алгоритм вычисления 25· X1.

В алгоритме применены следующие обозначения:

X1 — множимое;

P — частичная сумма (произведение);

S — промежуточный результат сдвига;

S<< - сдвиг влево с переносом числа S;

С — счетчик сдвигов Для реализации деления был выбран метод со сдвигом остатка влево.

Алгоритм деления приведен на рисунке 3.

Рисунок 3 — Алгоритм деления двух чисел методом сдвигом остатка влево В алгоритме применены следующие обозначения: D — частное; K — остаток от деления; X1 — делимое; X2 — делитель; С — счетчик бит; N — количество бит в делимом; B — текущий бит делимого; E — инвертированный признак заема при вычитании делителя из остатка.

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

Алгоритм многобайтного сложения приведен на рисунке 4.

Рисунок 4 — Алгоритм сложения многобайтных чисел X и Y.

В алгоритме применены следующие обозначения:

Tc — признак переноса;

N — количество байт в числе;

Xc — с-ый байт числа X;

Yc — с-ый байт числа Y;

С — счетчик байт;

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

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

Таким образом, используя разработанные алгоритмы можно составить структурную схему алгоритма программы для микропроцессора КР580ВМ80.

Структурная схема алгоритма программы приведена в приложении и состоит из четырех частей.

Первая часть — основная программа, в которой выполняются следующие действия:

В блоке 1.1 выполняется инициализация указателя стека;

в блоке 1.2 загружается число x1 в переменную tmp1, tmp3 и tmp4;

в блоке 1.3 обнуляется пятый байт переменных tmp1, tmp3 и tmp4;

в блоке 1.4 загружается число x2 в переменную tmp2 и обнуляется пятый байт переменной tmp2;

в блоке 1.5 вызывается подпрограмма многобайтного сложения чисел в переменных tmp4 и tmp2, результат записывается в переменную tmp4;

в блоке 1.5 вызывается подпрограмма умножения чисел в переменных tmp1 и tmp2, результат записывается в переменную tmp3;

блоки 1.6−1.12 соответствуют функциональному алгоритму на рисунке 2 (умножение x1 на 25):

в блоке 1.6 загружается число сдвигов в регистр C и в блоках 1.7−1.9 выполняется цикл сдвига на 3 разряда с учетом переноса, сдвиг на один разряд многобайтного числа выполняется при помощи подпрограммы в блоке 1.7;

в блоке 1.10 выполняется сложение результата сдвига (в переменной tmp1) и числа x1 (в переменной tmp3), результат сохраняется в tmp3;

в блоке 1.11 выполняется еще один сдвиг влево на один разряд числа в tmp1;

в блоке 1.12 вычисляется окончательный результат умножения путем сложения чисел в tmp1 и tmp3, результат сохраняется в tmp3;

в блоках 1.13−1.22 выполняется деление числа в переменной tmp4 (сумма x1 и x2) на число в tmp3 (произведение 25 и x1), результат записывается в tmp1: в блоке 1.13 обнуляются переменные частного tmp1 и остатка tmp2, в регистр С загружается количество бит в делимом (40) и сбрасывается признак переноса, далее идет цикл деления (блоки 1.14−1.22): делимое сдвигается влево (блок 1.14), остаток сдвигается влево (блок 1.15), из остатка вычитается делитель (блок 1.16) и если результат меньше нуля (блок 1.17), остаток восстанавливается (блоки 1.18), далее вычисляется очередной бит частного (блок 1.19) и частное сдвигается влево (блок 1.20), уменьшается на один число в регистре С (блок 1.21), выход из цикла происходит если в регистре С ноль (блок 1.22);

в блоке 1.23 значение функции в переменной tmp1 сохраняется в переменную y.

Вторая часть — подпрограмма сложения двух 5-и байтных двоичных чисел, адреса которых находятся в регистровых парах HL и DE соответственно. Результат помещается в ячейках памяти на место первого числа.

В блоке 2.1 сбрасывается признак переноса, в блоке 2.2 в регистр В загружается количество байт в числах, далее идет цикл сложения (блоки 2.3−2.9): байт второго числа загружается в аккумулятор (блок 2.3), складывается с первым числом (блок 2.4) и с признаком переноса, и сохраняется в память (блок 2.5), увеличиваются адреса байт (блоки 2.6,2.7), уменьшается на один число в регистре B (блок 2.8), выход из цикла происходит, если в регистре B ноль (блок 2.9).

Третья часть — подпрограмма вычитания двух 5-и байтных двоичных чисел, адреса которых находятся в регистровых парах HL и DE соответственно. Результат помещается в ячейках памяти на место второго числа.

В блоке 3.1 сбрасывается признак переноса, в блоке 3.2 в регистр В загружается количество байт в числах, далее идет цикл вычитания (блоки 3.3−3.9): байт второго числа загружается в аккумулятор (блок 3.3), из него вычитается байт первого числа и признак переноса (блок 3.4), и результат сохраняется в память (блок 3.5), увеличиваются адреса байт (блоки 3.6,3.7), уменьшается на один число в регистре B (блок 3.8), выход из цикла происходит, если в регистре B ноль (блок 3.9).

Четвертая часть — подпрограмма сдвига влево с учетом переноса 5-и байтового двоичного числа, адрес которого находится в регистровой паре HL:

В блоке 4.1 в регистр В загружается количество байт в числе, далее идет цикл сдвига (блоки 4.2−4.7): байт числа загружается в аккумулятор (блок 4.2), сдвигается (блок 4.3) и сохраняется в память (блок 4.4), увеличивается адрес байта (блок 4.5), уменьшается на один число в регистре B (блок 4.6), выход из цикла происходит если в регистре B ноль (блок 4.7).

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

3. Разработка программы на ассемблере

Согласно разработанной в предыдущем разделе структурной схемы программы была разработана программа на языке ассемблер для микропроцессора КР580ВМ80.

Листинг программы на языке ассемблер приведен в приложении.

Входные числа x1, x2 должны быть расположены в ячейках памяти, начиная с меток x1, x2, соответственно, и занимают каждое 4 байта. Результат вычисления функции располагается в ячейках памяти, начиная с метки y, и занимает также 4 байта.

В программе также используются четыре переменные tmp1, tmp2, tmp3, tmp4, которые используются для хранения промежуточных результатов операций. Каждая переменная занимает пять байт. Переменные располагаются в ячейках памяти по меткам:

tmp1 — метки tmp1L, tmp1H, tmp1HH;

tmp2 — метки tmp2L, tmp2H, tmp2HH;

tmp3 — метки tmp3L, tmp3H, tmp3HH;

tmp4 — метка tmp4L, tmp4H, tmp4HH.

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

Адресное пространство КР580ВМ80 составляет 64кБ. В данном пространстве должна располагаться память программ (ПЗУ) и память данных (ОЗУ). В памяти данных также должна быть определена область для стека. Так как при включении или сбросе процессор начинает выполнять команды с адреса 0, память программ должна начинаться с данного адреса.

Размещение программы и данных приведено на рисунке 5.

Рисунок 5 — Карта адресного пространства Размер ПЗУ Vп зависит от размера разработанной программы. Размер ОЗУ (Vд+Vс) зависит от размера памяти занимаемой используемыми переменными Vд, а также от необходимой памяти для стека Vс.

В расчетной части проведен расчет данных параметров:

ПЗУ: Vп=211 байт,

Vд=32 байта, Vс=2 байта ОЗУ: Vд+Vс=34 байта Начало адресного пространства данных:

Vп=211 (00D3h)

Начало адресного пространства стека:

Vп+Vд=243 (00F3h)

Конец используемого адресного пространства:

Vп+Vд+Vс=245 (00F5h)

Также в расчетной части проведен расчет времени работы программы:

Минимальное время работы tpmin=21,6345 мс Максимальное время работы tpmax=27,3945 мс

4. Расчетная часть.

Расчет объема ПЗУ Размер ПЗУ Vп зависит от размера разработанной программы. Расчет можно произвести по формуле:

где i — количество байт занимаемое командой, Ni — количество команд занимающих i байт.

Максимальное значение i равно 3, так как в данном процессоре команда может занимать максимум три байта.

В таблице 1 приведено количество команд в программе для разных значений i.

Таблица 1 — Количество команд, для разных значений i

Количество байт, I

Количество команд, Ni

Таким образом, общий объем памяти программ равен Vп=27+2· 5+3·58=211 байт.

Расчет объема ОЗУ Размер ОЗУ зависит от размера памяти занимаемой используемыми переменными Vд, а также от необходимой памяти для стека Vс.

В программе используется следующие переменные семь переменных: x1, x2, y занимают по четыре байта; tmp1, tmp2, tmp3, tmp4, занимают по пять байт.

Таким образом, размер памяти для переменных равен Vд=3· 4+4·5=32 байта.

В данной программе стек используется только при вызове подпрограмм. Так как при вызове подпрограммы в стеке сохраняется адрес возврата из подпрограммы, который занимает два байта, то для расчета памяти для стека необходимо подсчитать максимальное количество вложенных вызовов подпрограмм. В данной программе оно равно одному. Таким образом, размер памяти для стека равен Vc=2· 1=2 байта.

Расчет времени работы программы По заданию тактовая частота микропроцессора равна fT=2 МГц.

Время выполнения одного такта рассчитывается по формуле:

мкс Расчет времени работы программы можно произвести по формуле где фi — число тактов в команде, Ni — число команд, выполняющееся за фi, Тппj — время выполнения подпрограммы j.

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

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

В таблице 2 приведено количество команд в программе для разных значений фi, для команд основной программы.

Таблица 2 — Количество команд, для разных значений фi вне циклов

Количество тактов, фi

Количество команд, Ni

В основной программе присутствует цикл деления, который выполняется 40 раз, а также цикл сдвига при умножении, который выполняется 3 раза. В таблице 3 приведено количество команд в цикле, для разных значений фi.

Таблица 3 — Количество команд в циклах деления, для разных значений фi

Количество тактов, фi

Количество команд, Ni (Nimin / Nimax)

Цикл деления

Цикл сдвига

7 или 9

4 или 5

Таким образом, общее количество тактов основной программы равно 4· 2+7·2+10·10+13·4+16·20+17·4+40·(4+5+10·(7/9)+17·(4/5))+3·(5+10·10+17)= от 6808 до 8288 тактов.

В таблице 4 приведено количество тактов, за которое выполняется каждая подпрограмма.

Таблица 4 — Количество тактов, для разных значений фi

Подпрограмма

Количество тактов, Тппj (Tmin / Tmax)

Add40

11+46· 5+10=251

Sub40

11+46· 5+10=251

Ral40

7+38· 5+10=207

Таким образом, минимальное время выполнения программы равно tpmin=(6808+251· 3+207+40·(251+3·207)+3·207)?0.5мкс = 21,6345 мс, максимальное время выполнения программы равно tpmax=(8288+251· 3+207+40? ?(2· 251+3·207)+3·207) · 0.5 мкс = 27,3945 мс.

Заключение

В курсовой работе был разработан алгоритм и создана программа на ассемблере вычисления функции для микропроцессора КР580ВМ80.

Входные числами являются целые, положительные, 4-х байтные, двоичные числа x1, x2.

Результатом является, целое, положительное, 4-х байтное, двоичное число y.

Для выполнения отдельных операций были разработаны алгоритмы программного умножения, деления, сложения, вычитания и сдвига влево многобайтных чисел, которые отвечают поставленному спецтребованию — минимизировать объем памяти программы. Алгоритмы сложения, вычитания и сдвига влево реализованы в виде подпрограмм, также с целью уменьшить объем памяти программы.

Было произведено распределение адресного пространства для программы и данных и рассчитано время работы программы.

Размер необходимой памяти программ (ПЗУ) равен 211 байт. Программа размещается в памяти, начиная с адреса 0.

Размер необходимой памяти данных (ОЗУ) равен 34 байта. Данные размещаются по адресу 00D3h. Стек программы размещается по адресу 00F3h.

Время выполнения программы зависит от входных чисел и находится в пределах от 21,6345 до 27,3945 мс.

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

1. Н. П. Мольков, В. В. Фалин. Микропроцессоры и МЭВМ в РЭС. Муром, 2005 г.

2. Гилмор Ч.

Введение

в микропроцессорную технику, Мир, М., 1984 г.

3. Л. Н. Преснухин. Микропроцессоры. Лен. Издат. 1987 г.

Приложение Листинг программы

; программа вычисления функции y=(x1+x2)/(25*x1)

org 0000h

Start:

lxi sp, Stack

lhld x1; загрузка x1

shld tmp1L; [tmp1] = x1

shld tmp3L; [tmp3] = x1

shld tmp4L; [tmp4] = x1

lhld x1H

shld tmp1H

shld tmp3H

shld tmp4H

xra a

sta tmp1HH; загрузка нуля в 5-ый байт

sta tmp3HH

sta tmp4HH

lhld x2; загрузка x2

shld tmp2L; [tmp2] = x2

lhld x2H

shld tmp2H

sta tmp2HH; загрузка нуля в 5-ый байт

lxi h, tmp4L

lxi d, tmp2L

call Add40; [tmp4]=[tmp4]+[tmp2] -> x1+x2

mvi c, 3; [tmp1]=2*2*2*[tmp1] -> 8*x1

m1:

lxi h, tmp1L

call ral40; [tmp1]=2*[tmp1]

dcr c

jnz m1

lxi h, tmp3L

lxi d, tmp1L

call Add40; [tmp3]=[tmp3]+[tmp1] -> (8*x1+x1)=9*x1

lxi h, tmp1L

call ral40; [tmp1]=2*[tmp1] -> 16*x1

lxi h, tmp3L

lxi d, tmp1L

call Add40; [tmp3]=[tmp3]+[tmp1] -> (9*x1+16*x1)=25*x1

; —————————————————-;

; деление 5-и байтного числа на 5-и байтное,

; результат 4-х байтный

; [tmp1]=[tmp4]/[tmp3] -> (x1+x2)/(25*x1)

lxi h, 0000

shld tmp1L; обнуление результата [tmp1]

shld tmp1H

shld tmp2L; обнуление остатка [tmp2]

shld tmp2H

xra a

mvi c, 28h; счетчик бит делимого

; цикл для всех бит делимого (40 раз)

divlp:

lxi h, tmp4L

call Ral40; сдвиг делимого [tmp4] влево

lxi h, tmp2L

call Ral40; сдвиг остатка [tmp2] влево

lxi h, tmp3L

lxi d, tmp2L

call Sub40; [tmp2]=[tmp2]-[tmp3]

jnc NoAdd; остаток больше делителя?

lxi h, tmp2L; нет — восстанавливаем остаток

lxi d, tmp3L

call Add40; [tmp2]=[tmp2]+[tmp3]

NoAdd:

cmc

lxi h, tmp1L

call Ral40; получение бита результата в [tmp1]

dcr c

jnz divlp

; —————————————————-;

lhld tmp1L; копирование результата в y

shld y

lhld tmp1H

shld yH

jmp Start

; Подпрограмма

; сложение двух 5-и байтн. чисел

; [HL] = [opA]

; [DE] = [opB]

; [opA]=[opA]+[opB]

add40:

xra a

mvi b, 5

add40lp:

ldax d

adc m

mov m, a

inx h

inx d

dcr b

jnz add40lp

ret

; Подпрограмма

; вычитание двух 5-и байтн. чисел

; [HL] = [opA]

; [DE] = [opB]

; [opB]=[opB]-[opA]

sub40:

xra a

mvi b, 5

sub40lp:

ldax d

sbb m

stax d

inx h

inx d

dcr b

jnz sub40lp

ret

; Подпрограмма

; сдвиг через перенос 5-и байтн. числа

; [HL]=[opI]

; [opI]=Tc<<[opI]<

ral40:

mvi b, 5

ral40lp:

mov a, m

ral

mov m, a

inx h

dcr b

jnz ral40lp

ret

; память для хранения входных чисел и результата

x1 dw 0; двоич. число x1, 4 байта

x1H dw 0

x2 dw 0; двоич. число x2, 4 байта

x2H dw 0

y dw 0; двоич. число результат y, 4 байта

yH dw 0

; память для хранения промежуточных значений

tmp1L dw 0; временный буфер, 5 байт

tmp1H dw 0

tmp1HH db 0

tmp2L dw 0; временный буфер, 5 байт

tmp2H dw 0

tmp2HH db 0

tmp3L dw 0; временный буфер, 5 байт

tmp3H dw 0

tmp3HH db 0

tmp4L dw 0; временный буфер, 5 байт

tmp4H dw 0

tmp4HH db 0

Stack dw 0; стек

End

Показать весь текст
Заполнить форму текущей работой