Данный документ рассматривает использование среды ЯОЛС-М для моделирования устройств на примере реализации операции сложения с фиксированной запятой.
Для целей данного примера нам нужны два регистра, один из которых содержит первый операнд (и
после операции будет содержать результат), а второй содержит сумируемое\вычитаемое значение.
Предположим, что наши числа с фиксированной запятой имеют 5 разрядов для целой части и 3 разряда
для дробной части (предоставляя минимальную точность в виде 1/8, и общую длину в 8 бит).
Назовем их р0 и р1 соответственно:
объявить р0 (8), р1 (8)
В начале выполнения микропрограммы пользователем должны быть введены значения обоих регистров. Эта часть реализуется с помощью оператора ввести:
ввести р0 , р1
Если добавить строку печати запроса ввода, пользователю будет понятно назначение полей ввода даже без просмотра исходного кода программы:
печать "Введите р0, р1 (целая часть 5 бит, дробная часть 3 бита):"
ввести р0 , р1
Сложение с фиксированной запятой программно ничем не отличается от обычного сложения, поэтому эта часть пока остается так же за одну строку:
р0 + р1
После, можно добавить вывод результата,
печать р0
Полный код на данный момент будет таким:
объявить р0 (8), р1 (8)
печать "Введите р0, р1 (целая часть 5 бит, дробная часть 3 бита):"
ввести р0 , р1
р0 + р1
печать р0
В случае запуска, микропрограмма уже способна сложить два беззнаковых числа с фиксированной запятой. К примеру, 3.75 #00011110 + 1.5 #00001100 = 5.25 #00101010.
Для обработки знаков в данном случае можно использовать дополнительный код.
Ценой двух лишних битов в числах мы получаем однозначное представление знаков
и возможность обработки переполнения, что так же является немаловажной деталью.
Добавление знаковых битов делается простым расширением обоих переменных до 10 бит,
объявить р0 (10), р1 (10)
И добавлением заметки об этом в запрос ввода, который можно, ради этого случая, разбить на две строки:
печать "Введите р0, р1:"
печать "(2 бита знака, целая часть 5 бит, дробная часть 3 бита)"
Так же нужно обрабатывать переполнение. Переполнение в дополнительном коде определяется комбинациями знаковых разрядов 01 / 10, что можно было бы сделать двумя условиями,
если р0 (9:8) = #01
конец "Переполнение!"
если р0 (9:8) = #10
конец "Переполнение!"
Или же упростить до одного условия по несовпадению значений разрядов:
если р0 (8) <> р0 (9)
конец "Переполнение!"
Помимо переполнения, так же хорошим ходом является обработка знака, так как преобразование
чисел из прямого кода в обратный и наоборот -
для большинства людей не совсем привычная задача.
Для реобразования между двумя, нам нужно инвертировать число и добавить к нему 1,
если какой-либо из знаковых битов равен 1,
если р0 (8) = 0 идти_к 1
р0 (7:0)~~
р0 + 1
1:
Аналогичное применимо и для ввода, лишь с тем различием, что проверка знака требует опрос двух разрядов, а не одного.
если р0 (9:8) <> #11
идти_к 2
р0 (7:0)~~
р0 + 1
2:
Таким образом, после модификаций, код будет выглядеть следующим образом:
объявить р0 (10), р1 (10)
печать "Введите р0, р1:"
печать "(2 бита знака, целая часть 5 бит, дробная часть 3 бита)"
ввести р0 , р1
если р0 (9:8) <> #11
идти_к 2
р0 (7:0)~~
р0 + 1
2:
если р1 (9:8) <> #11
идти_к 3
р1 (7:0)~~
р1 + 1
3:
р0 + р1
если р0 (8) <> р0 (9)
конец "Переполнение!"
если р0 (8) = 0 идти_к 1
р0 (7:0)~~
р0 + 1
1:
печать р0
И работать полностью корректно - так, -3.25 #1100011010 + 1.5 #0000001100 = -1.75 #1100001110.