Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МУ_КП_1801.doc
Скачиваний:
13
Добавлен:
27.08.2019
Размер:
2.81 Mб
Скачать

5. Определение модуля числа

Напомним понятие модуля числа. Абсолютная величина или модуль, обозначается |x|. В случае вещественного аргумента — непрерывная кусочно-линейная функция, определённая следующим образом:

Для изменения знака числа в дополнительном коде число необходимо инвертировать и арифметически прибавить 1.

Рассмотрим программу, которая анализирует состояние знакового бита и изменяет знак при необходимости:

Адрес

Метка

Мнемокод

Комментарий

1000

TST R0

Проверить R0

BPL END

Если положительное – остановиться

NEG R0

Иначе изменить знак

1006

END

HALT

Остановиться

Программа имеет несколько недостатков:

1) Не сохраняется информация о факте изменения знака

2) Позволяет обрабатывать только 1- и 2-байтовые числа

Первый недостаток устраняется достаточно просто – выделяется ячейка памяти, которая будет хранить эту информацию. Например, так:

Адрес

Метка

Мнемокод

Комментарий

1000

TST R0

Проверить R0

SXT 400

Скопировать знак во «флаг»

BPL END

Если положительное – остановиться

NEG R0

Иначе изменить знак

1012

END

HALT

Остановиться

Для устранения второго недостатка воспльзоваться командой NEG не удасться. Например, дано трехбайтовое число, у которого необходимо получить модуль. Для удобства предположим, что число находиться в регистрах R0 и R1. Воспользуемся следующим признаком старшинства регистров: старший номер – старший регистр.

31

24

23

16

15

8

7

0

R1

R0

Старший регистр

Младший регистр

Ст. байт

Ср. байт

Мл. байт

Данное слово

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

Команда SXT «расширение знака» в данном случае не подходит, т.к. операнд является байтом, а команда работет только с 16-разрядными операндами. Поэтому можно воспользоваться особенностью выполнения команды MOV В.

Изменение знака в дополнительном коде, как отмечалось ранее, состоит из двух этапов: инвертирования и прибавления 1, причем 1 прибавляется арифметически. Это значит, что необходимо учитывать переносы между всеми байтами, как следствие, и между регистрами.

В результате код может принять следующий вид:

Адрес

Метка

Мнемокод

Комментарий

1000

MOV B R1,R1

Расширить знак младшего байта R1

TST R1

Проверить R1

SXT 400

Скопировать знак во «флаг»

BPL END

Если положительное – остановиться

COM R0

Инвертировать число целиком

COM R1

ADD #1,R0

Прибавить 1

ADC R1

1024

END

HALT

Остановиться

Програма корректно работает со всеми числами, кроме «отрицательного нуля». Напомним, что «отрицательный ноль» - представляет собой число, содержащее 1 в знаковом бите, при нулевых остальных битах числа. При изменении знака число, как и просто 0, не изменяется. Распологая его в регистрах R0 и R1 получим R0 = 0, R1 = 200. Даже если в старший байт регистра R1 дописать произвольное количество 1, на выходе получается R1 = 200.

Этот момент наглядно демонстрирует необходимость разработки специального обработчика для данного числа. Например, считать его 0.