1   2   3   4   5   6   7
Ім'я файлу: Арх_комп_КСД12_Гайдук_КР.pdf
Розширення: pdf
Розмір: 997кб.
Дата: 13.02.2022
скачати
Пов'язані файли:
пояснительная_записка.doc
3. Представление вещественных чисел в памяти ЭВМ Общие сведения о числах с плавающей запятой Помимо целых ( ) и вещественных ( ) чисел, различают также числа с фиксированной и с плавающей точкой. Причем, ненужно путаться в этих понятиях как числа с фиксированной точкой иногда еще говорят "фиксированной запятой, таки числа с плавающей точкой, - это все вещественные числа, и точка в них отделяет целую часть от дробной. Вариации в названии
("точка"/"запятая") обусловлены тем, что в разных странах действуют различные стандарты представления чисел в странах СНГ, например, целую и дробную части друг от друга отделяют запятой, а в США – с помощью точки. Наиболее привычна нам запись вещественных чисел с фиксированной точкой. Например
125.3689 Положение разделительной точки в данной форме записи мы менять не можем, т.к. если его изменить, то это уже будет совсем другое число, потому это представление вещественных чисел и называется формой записи с фиксированной точкой. В чем ее недостаток Например, если число очень маленькое
0.000000000000000000000000000000000355002 или очень большое
35562336500000000000000045552114000000.5555555555 то оперировать столь длинными записями как минимум неудобно, ведь разрядов получается много, а информативности в них мало. Если число очень маленькое, то мы будем иметь массу не особо информативных нулей, если число очень большое, то последние его разряды также не представляют особого интереса, т.к., например, если бы мы точно измерили длину экватора, и выразили в сантиметрах, то разве интересовали бы нас сантиметры на фоне почти 40 тыс. км Другая проблема заключается в том, что если числа обрабатываются с помощью ЭВМ, тона их представление в памяти машины отводится фиксированное количество разрядов, и если число слишком маленькое, то может получиться так, что места хватит только на нули, а вся информативная часть числа (значащие цифры) останется "за кадром. Поэтому, в научной сфере чаще используют форму записи с плавающей запятой, также еще называемую экспоненциальной. Например,
0,00034502 = 3,4502*10^-4 12853,37 = 1,285337*10^4 При такой форме записи, мы можем свободно перемещать положение запятой влево или вправо, не забывая при этом соответствующим образом менять показатель степени. Перемещение

12 запятой вправо приводит к уменьшению показателя степени (число перед степенью десятки увеличивается – следовательно, домножать его уже нужно на меньшую степень десяти (для сохранения равенства исходному, перемещение влево – к увеличению (рассуждения аналогичны предыдущим) – все это должно быть очевидным, в общем-то. Благодаря свободе в перемещении положения запятой, эта форма представления вещественных чисел и стала называться формой с "плавающей" запятой. Тов случае экспоненциальной записи числа, можно выделить три компоненты этой записи порядок – показатель степени десяти (напомним, что показатель степени и степень – это разные вещи так, в записи 2^3 = 8, 8 – это степень (я степень двойки, а 3 – это показатель степени мантисса – то, что умножается на степень десяти знак – знак числа. В общем виде это можно записать так где – знак ("+" или "-"), – мантисса, – порядок. Например, в числе знак – "-", мантисса -
, порядок – 5. Суть экспоненциальной записи понимается еще лучше, если вспомнить, что любое число представимо в виде полинома
∑ где – число (в общем случае – вещественное, – основание системы исчисления,
-
-й разряд числа. Например Экспоненциальная форма записи – это, по сути, тот же полином, нос вынесенной за скобки степенью основания системы исчисления – изменяя показатель степени, мы можем произвольно менять в числе положение разделительной точки (идет за разрядом, при котором основание системы исчисления находится в й степени. Также важно понимать, что в виде полинома ив экспоненциальной форме может быть представлено число любой системы исчисления будь-то десятичная, двоичная, или троичная и т.д. Итак, с вопросами компактного представления слишком больших или маленьких чисел и сохранения, при этом, максимального числа значащих цифр, вроде бы разобрались – все это становится возможным благодаря экспоненциальной форме записи. Однако, есть еще одно "но. Рассмотрим пример число 0,00002334 в экспоненциальной форме можно записать разными способами например, так й способ й способ Допустим, что устройство ЭВМ может хранить только первые 4 разряда мантиссы предположим, что числа хранятся в ЭВМ в десятичном виде, а остальные будут отброшены, что ведет к потере точности. Тогда в первом случае вся мантисса поместится в соответствующую область памяти ЭВМ, а во втором случае часть будет отсечена, и поместится лишь – два

13 других разряда будут утеряны, хотя в обоих случаях число одно и тоже. Дабы избежать подобного казуса, применяют т.н. нормализацию мантиссы – запятая ставится после первой значащей цифры слева. Нормализация позволяет сохранить действительно максимальное количество значащих цифр. Тов первом случае (из вышеприведенного примера) мантисса была нормализована, а во втором – нет. Также несложно видеть, что мантисса всегда находится в диапазоне
, где – основание системы исчисления. Например, для десятичной системы, нормализованная мантисса всегда будет в пределах
, для двоичной – в пределах
– те, от 1 дох в десятичной (не будем забывать, что двоичная система позволяет выражать не только целые, но и вещественные числа. Исключение составляет разве что ноль – представление ноля – это уже вопрос договоренности. Машинное представление чисел с плавающей запятой Наиболее распространенный стандарт машинного представления чисел с плавающей запятой
– это IEEE-754, который мы и будем рассматривать. В зависимости оттого, сколько байт отводится на число, различают такие форматы число половинной точности (2 байта число одинарной точности (4 байта число двойной точности (8 байт число четверной точности (16 байт. Все эти форматы друг от друга отличаются только размером и отводимым количеством разрядов на мантиссу и порядок, а в остальном полностью идентичны, поэтому, для понимания стандарта, достаточно рассмотреть один из форматов. Рассмотрим формат одинарной точности. На число отводится 4 байта (32 бита) (рис. 3.1). й бит указывает на знак (0 – положительное число (ноль – также положительное число, 1 – отрицательное. Биты 30 .. 23 (итого,
1 байт) указывают на порядок числа. Биты 22 .. 0 (итого, 23 бита) отводятся под мантиссу. Рис. 3.1 – Машинное представление вещественного числа одинарной точности. Преобразование десятичного числа в машинный код рассмотрим на примере. Пусть дано число -12,364. Знак числа отрицательный – следовательно, й бит будет установлен в единицу. Берем модуль числа 12,364. Переводим его в двоичную систему исчисления (напомним, что целая и дробная части переводятся отдельно
0 364 0 736 1 664 0 728 1 472 1 328 1 456 0 944 0 656 0 912 1 888 1 312 1 824 1 776 0 624 1 648 1 552 1 248 1 296 1 104 0 496

14 0 592 0 208 0 992 1 184 0 416 1 984 0 368 0 832 1 968 Итак, в двоичную систему перевели. В принципе, полученное двоичное число из формы записи с фиксированной запятой "легким движением руки" превращается в число в экспоненциальной форме Выполним нормализацию полученного числа Итак, после нормализации мантисса попала в интервала порядок стал равным 3 запятую сдвинули на 3 разряда влево. Если число – не ноль, то первый разряд мантиссы всегда равен единице. Следовательно, нет смысла хранить его в памяти – вместо того, чтобы хранить разряд, значение которого для любого числа мы итак знаем, можно "захватить" еще один дополнительный разряд справа, повысив точность представления числа. Отбросим первый разряд мантиссы (эту единицу мы будем просто подразумевать, отсчитаем вправо 23 бита из оставшихся, и получим то. нашу мантиссу. Но, все не так просто. Подобно тому, как при операциях с десятичными числами мы используем округление, также округление выполняется и двоичных чисел. Так, если, отсчитав вправо 23 бита, мы обнаруживаем, что 24- бит – единица, то мантиссу нужно округлить. Делается это просто прибавлением к полученному разрядному числу единицы. В нашем случае имеем й бит – единица Итого, мантисса числа Порядок числа равен +3. Не будем забывать, что, в общем случае, порядок может быть и отрицательным (если запятую сдвигать при нормализации вправо. Дабы не хранить еще и знак порядка (помимо знака числа в целом, было введено понятие порядка со смещением (смещенного порядка. Он получается прибавлением к истинному значению порядка такого смещения, чтоб сумма при минимальном истинном значении порядка была равна нулю. Так, если мин. значение порядка –
(-127), а максимальное – (+128), то, добавив смещение +127, мы получим смещенный порядок, который всегда будет только положительными будет изменяться в диапазоне 0-255. Для хранения
ЧБЗ в диапазоне 0-255, как известно, достаточно одного байта. Итак, истинный порядок в рассматриваемом примере равен +3. Добавляем 127, получаем смещенный порядок (иначе еще, машинный порядок Зная мантиссу, порядок и знак числа, можем записать его полностью
11000001010001011101001011110010 Разбиваем на тетрады, получаем шестнадцатеричное машинное представление
1100 0001 0100 0101 1101 0010 1111 0010

15
C145D2F2 Итого, -12,364 (дес. представление) = C145D2F2 (шест. машинное представление) Проверить корректность выполненного кодирования можно разными способами. Например указать требуемое число в сегменте данных ассемблерной программы, и посмотреть в отладчике воспользоваться онлайн-конвертером IEEE-754; написать программу на одном из ЯВУ и т.д. Рассмотрим все три перечисленных способа. Способ 1. Проверка с помощью отладчика. Напишем на ассемблере что-то вроде этого (листинг 3.1): Листинг 3.1

.model small
.stack 100h
.data dd -12.364
.code begin: mov ax, @data mov ds, ax nop mov ax, 4c00h int 21h end begin Откомпилируем, и посмотрим сегмент данных в отладчике (рис. 3.2): Рис. 3.2 – Проверка корректности конвертации с помощью отладчика.

16 Не забывая, что в архитектуре Intel младшие байты размещаются по младшим адресам, убеждаемся в корректности выполненного ранее преобразования. Способ 2. Проверка с помощью онлайн конвертера. Переходим по адресу http://www.h-schmidt.net/FloatConverter/IEEE754de.html
В поле Decimal
Representation вводим наше число в десятичной форме, кликаем по любому свободному месту формы, и получаем результат (рис. 3.3). Рис. 3.3 - Проверка корректности конвертации с помощью онлайн-конвертера. Способ 3. Написание собственной программы-конвертера. Дабы по-настоящему понять тот или иной алгоритм, его нужно только запрограммировать своими руками. Ниже представлен пример работы программы-конвертера, преобразующей число из его десятичного представления в машинное представление согласно стандарту IEEE-754. Листинг программы приведен в приложении 1. Рис. 3.4 – Программа конвертер (кодер) на С.

17 Заметим, что между типами данных С/С++ и упомянутыми выше форматами машинного представления чисел с плавающей запятой имеется соответствие одинарная точность (4 байта) – float; двойная точность (8 байт) – double. Что касается алгоритма обратной конвертации – машинного кода в десятичное представление, то он вполне очевиден из машинного порядка вычитаем смещение – получаем истинный порядок к мантиссе слева добавляем скрытую единицу ставим разделительную запятую в нужное место, в соответствии с истинным порядком переводим в десятичную систему полученное двоичное число устанавливаем знак. В учебных целях, обратный перевод также был выполнен в виде программы на С, пример работы которой показан на рисунке ниже (риса листинг находится в приложении 2. Рис. 3.5 – Программа конвертер (декодер) на С.
4. Выбор микроконтроллера Для удобного обращения с МПС, она должна быть снабжена, как минимум, клавиатурой для ввода исходных данных (а это уже займет минимум один порт МК), ЖК-дисплеем для индикации вводимых данных и прочей информации (даже при использовании 4-битной шины данных, с учетом х линий управления, в целом это, примерно, также займет один порт, на управление одним шаговым двигателем также нужен один порт, но можно использовать мультиплексор, дабы через один порт управлять двумя двигателями. Плюс, еще один порт на подключение кнопок управления. Итого, МК должен иметь минимум 4 порта. Если инкремент часового угла в режиме ведения выполнять разв сто 8-миразрядного таймера не хватит (даже при максимальном делении частоты) – нужен 16-тиразрядный таймер.

18 Основная часть программы выполняется примерно за 350 тыс. тактов ЦП (определено в отладчике AVR Studio). При частоте 4 МГц расчеты займут примерно 0,1 с. Следовательно, МК с частотой внутреннего генератора равной 4 или 8 МГц вполне подойдет (если не использовать кварц. Размер программы составляет примерно 2,5 Кб. На основании вышеприведенных требований можно заключить, что МК ATmega8535 вполне подходит для решения поставленной задачи, т.к. он имеет 4 порта, три таймера (один из них 16- тиразрядный – TC1), рабочую тактовую частоту от 0 до 16 МГц и объем памяти, равный 8
Кб.
5. Определение регистров Мнемоники регистров определены в файле def_reg.inc, и представлены ниже
;*******************************************************************************
;
; Определение регистров.
;
;*******************************************************************************
.def ct_t = r15 ; Счетчик итераций в тригонометрических вычислениях.
.def sgn = r16 ; Доп. переменная в тригонометрических операциях (знак.
.def temp = r17 ; Временный регистр.
.def acc = r18 ; Аккумуляторный регистр.
.def cnt = r19 ; Счетчик.
.def pA = r20 ; й операнд.
.def mAH = r21
.def mAM = r22
.def mAL = r23
.def pB = r24 ; й операнд.
.def mBH = r25
.def mBM = r26
.def mBL = r27
.def _pC = r28 ; Произведение / частное.
.def mCH = r29
.def mCM = r30
.def mCL = r31 Ввиду того, что микроконтроллер 8-миразрядный, для представления одного вещественного числа требуется 4 регистра. То, описаны следующие составные регистры регистр A – r20-r23 – используется для хранения первого слагаемого, уменьшаемого, делимого, первого множителя, а также как регистр-аккумулятор; регистр B – r24-r27 – используется для хранения второго слагаемого, вычитаемого, делителя, второго множителя, а также для хранения промежуточных результатов регистр C – r28-r31 – используется для хранения суммы частичных произведений приумножении, для формирования частного отделения, а также для хранения промежуточных результатов. То, регистр A представлен четырьмя 8-миразрядными регистрами pA, mAH, mAM, mAL, регистр B представлен регистрами pB, mBH, mBM, mBL, регистр C представлен регистрами _pC, mCH, mCM, mCL.

19 Регистр pX используется для хранения порядка числа (после его восстановления из базового формата – об этом детальнее будет сказано при рассмотрении вспомогательных функций при выполнении арифметических операций, регистры mXH, mXM, mXL – для хранения мантиссы числа именно мантисса в них также будет только в случае выполненного восстановления числа из базового формата, где X – буква составного регистра. К названию регистра pC добавлено подчеркивание во избежание переопределения регистра- счетчика команд. Регистр cnt используется как переменная-счетчик в циклах в модулях арифеметических операций. Регистр acc используется как аккумулятор в циклах в модулях арифеметических операций. Регистр temp используется как временная переменная. Регистр sgn используется для хранения знака слагаемого при разложении тригонометрических функций вряд Тейлора. Регистр ct_t используется как переменная-счетчик в циклах при разложении тригонометрических функций вряд Тейлора. Ввиду того, что это регистр с номером менее 16-ти, он не может участвовать в опрациях с непосредственной адресацией, что обусловлено архитектурой микроконтроллеров AVR.
6. Арифметические операции с вещественными числами Детальное описание арифметических операций над числами с плавающей запятой займет слишком много места, поэтому здесь они будут описаны довольно кратко. Подробное описание соответствующих алгоритмов можно найти в книге В.Я. Хартова "Микроконтроллеры AVR. Практикум для начинающих.
6.1 Вспомогательные функции Прежде, чем перейти к расмотрению реализации каждой операции в отдельности, рассмотрим некоторые вспомогательные функции (подпрограммы, описанные в файле acc_fun.asm:
; Проверка операнда A на равенство нулю. cp_A_0: mov acc, pA ; Логическое сложение всех х байт or acc, mAH ; и проверка флага Z. or acc, mAM or acc, mAL ret Выполняется логическое сложение всех байт числа – если в результате устанавливается флаг
Z (нулевой результат, то и все число, значит, было равно нулю.
; Проверка операнда B на равенство нулю. cp_B_0: mov acc, pB ; Логическое сложение всех х байт or acc, mBH ; и проверка флага Z. or acc, mBM or acc, mBL ret

20 Подпрограмма аналогична предыдущей.
; Обмен операндов местами. swapAB: eor pA, pB ; x <- x xor y eor pB, pA ; y <- (x xor y) xor y = x xor (y xor y) = x eor pA, pB ; x <- (x xor y) xor x = x xor y xor x = y eor mAL, mBL eor mBL, mAL eor mAL, mBL eor mAM, mBM eor mBM, mAM eor mAM, mBM eor mAH, mBH eor mBH, mAH eor mAH, mBH ret Выполняет обмен содержимого двух операндов без привлечения доп. переменной. Содержимое каждой пары регистров обменивается затри операции. Доказательство справедливости подобного подхода приведено в комментариях к коду.
; Восстановление операнда A из базового формата. rec: lsl mAH ; Выталкиваем мл. разряд порядка в С. rol pA ; Сдвиг влево через перенос. Подтяжка из Сна место. ori mAH, 0x80 ; Скрытая 1 в й разряд. ret Выполняет восстановление числа из базового формата. Это значит, что порядок (8 бит) смещается на 1 разряд влево, и полностью занимает регистра в освободившийся й бит помещается скрытая единица мантиссы – та самая, которая опускается при формировании кода числа в соответствии со стандартом IEEE-754. Мантисса то. оказывается полностью в регистрах mAH старшая часть мантиссы, mAM (средняя часть мантиссы, mAL (младшая часть мантиссы. Знак числа перед вызовом подпрограммы rec заносится в флаг T процессора.
; Сдвиг мантиссы вправо при выравнивании порядков. rshift: lsr mAH ; Мл. разряд при этом выталкивается в С. ror mAM ror mAL clc ; Могли вытолкнуть 1 – сбрасываем C. ret Выполняет сдвиг мантиссы числа вправо на один разряд.
; Сдвиг мантиссы влево. lshift: clc rol mAL

21 rol mAM rol mAH clc ret Выполняет сдвиг мантиссы числа влево на один разряд.
; Упаковка результата. pack: mov pB, pA ; pB <- pA. clc ; C = 0. По умолчанию положительное. brtc set_sign ; if T == 0. sec ; C = 1. set_sign: ror pA ; Что в С положили, то и втянем. clc ; То, что вытолкнули, нам не надо. bst pB, 0 ; T <- pB(0). Мл. разряд порядка. bld mAH, 7 ; mAH(7) <- T. ret Выполняет упаковку числа в базовый формат старшая единица мантиссы убирается, порядок сдвигается на один разряд вправо, а знак восстанавливается из флага T процессора.

1   2   3   4   5   6   7

скачати

© Усі права захищені
написати до нас