Эта статья по большей части для совсем начинающих. Если вы хорошо разбираетесь в системах счисления, можете обратить внимание лишь на особенности синтаксиса ассемблера FASM в конце статьи.
На самом деле процессор работает только с двоичными числами, состоящими из единиц и нулей В виде двоичных чисел хранятся и обрабатываются все данные и команды любой программы. Однако, двоичная запись чисел слишком громоздка и неудобна для человека, поэтому в программах на ассемблере используются и другие системы счисления: десятичная, шестнадцатеричная и восьмеричная.
Немного теории
Прежде всего разберёмся, в чём различие между системами счисления. Любое десятичное число можно представить в таком виде:
12310 = 1·10 2 + 2·10 1 + 3·10 0
Индекс внизу обозначает, что это десятичное число. Цифра каждого разряда умножается на 10 в степени, равной номеру разряда, если считать с нуля справа налево. В более общем виде:
где a, b и с — какие-то цифры, а r — основание системы счисления. Для десятичной системы r = 10, для двоичной — r = 2, для троичной r = 3 и т.д. Например, то же самое число в других системах:
КАК НАУЧИТЬСЯ СЧИТАТЬ ДРОБИ / ВСЕГО 3 ПРАВИЛА
4435 = 4·5 2 + 4·5 1 + 3·5 0 = 4·25 + 4·5 + 3·1 = 12310 (пятеричная система)
1738 = 1·8 2 + 7·8 1 + 3·8 0 = 1·64 + 7·8 + 3·1 = 12310 (восьмеричная система)
11110112 = 1·2 6 + 1·2 5 + 1·2 4 + 1·2 3 + 0·2 2 + 1·2 1 + 1·2 0 = 1·64 + 1·32 + 1·16 + 1·8 + 0·4 + 1·2 + 1·1 = 12310 (двоичная система)
Шестнадцатеричная система
В шестнадцатеричной системе для обозначения цифр больше 9 используются буквы A = 10, B = 11, C = 12, D = 13, E = 14, F = 15. Например:
C716 = 12·16 1 + 7·16 0 = 12·16 + 7·1 = 19910
Удобство шестнадцатеричной системы в том, что в неё очень легко можно переводить двоичные числа (и в обратную сторону тоже). Четыре разряда двоичного числа (тетрада) представляются одним разрядом шестнадцатеричного. Для перевода достаточно разбить число на группы по 4 бита и заменить каждую тетраду соответствующей шестнадцатеричной цифрой.
| 0000 | |
| 0001 | 1 |
| 0010 | 2 |
| 0011 | 3 |
| 0100 | 4 |
| 0101 | 5 |
| 0110 | 6 |
| 0111 | 7 |
| 1000 | 8 |
| 1001 | 9 |
| 1010 | A |
| 1011 | B |
| 1100 | C |
| 1101 | D |
| 1110 | E |
| 1111 | F |
Для записи одного байта требуется всего 2 шестнадцатеричные цифры:
Восьмеричная система
Восьмеричная система также удобна для представления двоичных чисел, хотя она используется намного реже, чем шестнадцатеричная. Для быстрого перевода надо разбить двоичное число на группы по 3 разряда (триплеты или триады).
| 000 | |
| 001 | 1 |
| 010 | 2 |
| 011 | 3 |
| 100 | 4 |
| 101 | 5 |
| 110 | 6 |
| 111 | 7 |
КАК РАБОТАЮТ ЧИСЛА С ПЛАВАЮЩЕЙ ТОЧКОЙ | ОСНОВЫ ПРОГРАММИРОВАНИЯ
Например: 001 110 1012 = 1658
Синтаксис ассемблера FASM
По умолчанию, число в программе воспринимается ассемблером как десятичное. Чтобы обозначить двоичное число, необходимо к нему в конце добавить символ ’b’. Восьмеричное число обозначается аналогично с помощью символа ’o’. Для записи шестнадцатеричного числа FASM поддерживает 3 формы записи:
- перед числом записываются символы ’0x’ (как в C/C++);
- перед числом записывается символ ’$’ (как в Pascal);
- после числа записывается символ ’h’. Если шестнадцатеричное число начинается с буквы, необходимо добавить в начале ноль (иначе непонятно, число это или имя метки).
Этот синтаксис используется как при объявлении данных, так и в командах. Вот примеры записи чисел во всех четырёх системах:
Источник: asmbase.ru
1.3. Как записываются числа в разных системах счисления в языках программирования.
Си. 16-ричные числа предваряются 0x или 0X: 0xD5, 0X1634. 8-ричные числа предваряются нулем: 0204. Кроме того, числа, двоичное представление которых содержит 8 разрядов (т.е. байт, который будет определен чуть ниже) могут быть записаны так: ddd — в восьмеричном представлении, xdd — в 16-ричном (здесь d — цифра). Например, число 27 = 33 = x1B (проверьте).
Турбо Ассемблер. Это транслятор языка для записи машинных команд. Подробный разговор о нем впереди. Но с записью чисел уместно познакомиться уже сейчас.
Число обязательно должно начинаться с арабской цифры 0 – 9. Когда Турбо Ассемблер встречает в программе число, он сначала анализирует последний символ числа (суффикс, или постфикс). Вот таблица суффиксов (допускаются как прописные, так и строчные буквы).
Таблица 1.2. Суффиксы чисел в языке Ассемблера.
Если суффикс отсутствует, то число считается десятичным.
Пример. 68, 174d, 956D — десятичные числа, ABCh — ошибка! (Число должно начинаться с цифры, иначе Ассемблер воспринимает его как символическое имя). Чтобы исправить ошибку, нужно предварить такое число нулем. 0ABCh, 174dH, 956Dh, 1011Bh — 16-ричные числа, 1011B — двоичное число.
Упражнение 1.5. Определить, какие из следующих чисел правильно записаны на языке Ассемблера, указать для них систему счисления: a) 0A5; b) 102B; c) ffffh; d) 6234; e) 6234h.
На практике суффикс D, конечно, не используется. Достаточно запомнить, что в программе на Ассемблере число должно начинаться с 0 – 9, и не забывать обязательно ставить суффиксы H и B у 16-ричных и двоичных чисел.
Казалось бы, приведены излишние подробности. Но при использовании отладчика Turbo Debugger (сокращенно TD) у начинающих нередко возникают непонятные для них ситуации. Сначала отметим, что в отличие от Ассемблера отладчик по умолчанию воспринимает числа как 16-ричные.
Итак, отладчик запрашивает адрес — вводим, допустим, число 180с (без суффикса h) — все в порядке (отображается информация, расположенная по адресу 180Ch). Но если вводим 180d, то с удивлением видим, что отладчик отображает информацию, начиная с адреса 00B4h, а если вводим 1A0D, то отладчик выдает сообщение: Syntax error (синтаксическая ошибка), и обращение к Справке (Help) ничего не проясняет. Теперь вы должны понимать причины такой реакции отладчика.
1.4. Структура ячейки памяти.
Наименьшая единица информации — бит (bit — сокращение от английского BInary digiT — двоичная цифра). Бит принимает два значения, которые кодируются нулем и единицей. Тем самым описываются два уровня сигнала, два состояния элемента и т.д. Если значение бита равно 1, то говорят, что он «установлен», если 0 — то «сброшен».
Ссылаться на каждый бит памяти сложно, поэтому их объединяют в группы и рассматривают это объединение как единое целое. Наименьшей группой бит, к которым можно обращаться, является байт (byte — кусок). Его составляют 8 бит. Биты нумеруют так, как показано на рисунке 1.2: справа налево, начиная с нулевого
Источник: studfile.net
О представлении чисел в ЭВМ. Когда запятая плавает
Представление рациональных чисел в виде обыкновенных дробей удобно и полезно, но для нас все таки более привычны десятичные дроби. И их представление в виде чисел с фиксированной запятой позволяет работать с ними быстро и удобно. Но все таки, числа с фиксированной запятой не в состоянии покрыть все потребности в числовой обработке обработке.
Проблема возникает при работе с очень большими или очень малыми числами. А если еще учесть, что нужно выполнять арифметические операции с числами из всего диапазона. Это неудобно даже на бумаге. Но математики, разумеется, нашли решение этой проблемы. И называется оно
Научная, или экспоненциальная, форма записи чисел
С тапкой формой записи все знакомятся еще в школе, но все таки, полезно будет напомнить, что это такое.
Давайте представим, что нам нужно измерять и записывать вес различных предметов. Сразу возникает вопрос, записывать будем в граммах, килограммах, центнерах, тоннах? Но мы же знаем, что все несколько проще, так как 1 кг это 1000 г, а 1 ц это 100 кг, и так далее. Поэтому легко можем записать измеренный вес в любых единицах измерения. Например,
123 г = 0.123 кг = 0.00123 ц = 0.000123 т
1.5 т = 1500 кг = 1500000 г
То есть, фактически у нас есть некоторое число и масштабный множитель. И мы можем записать, например, так
123 г = 123 / 1000 кг = 123 / 100000 ц
1.5 т = 1.5 * 1000 кг = 1.5 * 1000000 г
Но записывать в таком виде неудобно. Однако, масштабный множитель у нас это число 10 в некоторой целой степени. И мы вполне можем, вместо длинного ряда нулей, просто записывать эту степень масштабного множителя. Будет гораздо короче. Особенно, для очень больших и очень малых чисел
Экспоненциальная, научная, форма записи чисел
Это и называется научной, точнее, экспоненциальной, формой записи чисел. Она удобна на бумаге, менее удобна в печатных книгах (требует использования дополнительных шрифтов), но с появлением вычислительных машин появилось небольшое затруднение. Дело в том, что набор шрифтов печатающих устройств первых ЭВМ был ограниченным, куда меньшим, чем типографский набор. Да и клавиатуры устройств ввода имели ограничения по количеству клавиш.
Поэтому стандартная, математическая, запись и оказалась проблематичной. Выход был найден в виде несколько измененных правил записи. Например, можно было записывать так
0.123 = 123 * 10 ^ -3
Здесь звездочка является стандартной заменой символа операции умножения (использовался и классический математический символ х), а стрелка вверх обозначает операцию возведения в степень. Такая запись довольно близка к математической, но ее можно и упростить.
0.123 = 123Е-3 = 123е-3
То есть, мантисса и порядок, без явного указания основания системы счисления, так как оно всегда 10. Буква Е, которая отделяет мантиссу от порядка, является сокращением от аббревиатуры exp — экспонента.
Нормализованная форма записи
Рассмотренный ранее пример записи числа 0.123 в виде 123е-3 можно записать и по другому
123е-3 = 1.23е-1 = 12.3е-2
Причем все варианты соответствуют одному и тому же числу, разница только в масштабном множителе — порядке. Для исключения неоднозначности было введено понятие нормализованной формы записи.
В нормализованной форме записи мантисса должна находиться в диапазоне
Другими словами, мантисса, рациональное число в десятичной форме записи, должно иметь целую часть в виде цифры от 1 до 9. Исключением является число в точности равное 0. Поэтому нормализованной формой записи будет именно
Почему запятая плавающая?
Давайте ненадолго вернемся к рациональным числам в форме с фиксированной запятой. Почему в них запятая именно «фиксированная»? Ведь мы свободно могли разместить запятую (десятичную точку) в любом месте числа. Это немного усложняло операции с числами у которых запятая находится в разных позициях, но не более того.
Все правильно. Поскольку числа с фиксированной запятой это рациональные числа записанные в виде десятичной дроби, мы вместо знаменателя записывали (хранили как атрибут числа) количество цифр после запятой. Это просто несколько иная форма записи, и не более того. Число оставалось рациональным.
Фиксированность запятой при этом заключается в том, что в результате операции положение запятой не могло измениться. Запятая оставалась ровно в том же месте, что и в числах участвующих в операции
Перед операцией сложения мы выполнили приведение положения запятой слагаемых, что и определило положение запятой результата. Точно так же все выглядит и для других операций (вычитание, умножение, деление). А это может приводить к довольно интересной, но ошибочной , ситуации
123.5 / 1000000 = 0.0
Как же так? Результат не должен быть равным 0.0! Он и не равен, он просто не может быть представлен в виде числа с фиксированной запятой с одной цифрой после в дробной части.
Если мы разрешим запятой (десятичной точке) свободно изменять свое положение, все встает на свои места
123.5 / 1000000 = 0.0001235
Как видно, положение запятой действительно изменилось. Именно это и позволило показать все цифры в дробной части результата. Вот это и называется плавающей запятой. На самом деле, в обычной жизни нам привычна именно запись чисел в форме с плавающей запятой, а не с фиксированной.
Преставление чисел с плавающей запятой и научная форма
В форме с плавающей запятой записываются, как мы уже знаем, рациональные числа. А в ЭВМ мы хранили рациональное число как пару чисел, числитель и знаменатель. Для рациональных чисел записанных в виде десятичной дроби можно было хранить не знаменатель, а количество цифр после запятой.
Именно так мы и поступали для чисел с фиксированной запятой. Более того, количество цифр после запятой можно было вообще не хранить, если оно остается неизменным для всех чисел в программе. Это позволяет экономить память.
Но для чисел с плавающей запятой мы уже обязаны хранить всю информацию о числе. Однако, хранить количество цифр после запятой неудобно. Мы уже рассматривали это ранее, проблемы возникают с очень большими или очень маленькими числами.
И тут нам на помощь приходит научная форма записи. Собственно говоря, для этого она и была введена. А значит, рациональное число в форме с плавающей запятой у нас будет представлено парой чисел, как и обыкновенная дробь. Только теперь это будут мантисса и порядок.