Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
01юьб тж.doc
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
1.62 Mб
Скачать

Представление данных

На самом нижнем уровне оперативную память можно рассматривать как массив битов. Один бит хранит значение 0 или 1. Но про­цессору неудобно работать с памятью на уровне битов, поэтому реально ОЗУ орга­низовано как последовательность ячеек - байтов. Таким образом, наименьший доступный элемент памяти для процессора − это байт, а не бит.

В байте биты нумеруются справа налево от 0 до 7. Бит с номером ноль называется младшим, бит с номером семь – старшим. Каждому байту соответствует свой уникальный адрес, называемый физическим адресом.

Следующим по размеру элементарным понятием является слово. Слово состоит из двух байтов, младшего и старшего. Существуют также и двойное слово, и учетверенное слово (рис. 1).

Рис. 1. Представление данных

Интерпретация хранимого в памяти значения зависит от определенных условий, которые и придают ему смысл. Для примера допустим, что программа поместила десятичное число 65 в ячейку памяти по адресу 0. Теперь нулевой байт хранит последовательность битов 01000001, так как 65 в двоичной системе счисления это 01000001 (рис. 1). Между тем отладочная программа отразит его как 41, т.е. как шестнадцатеричное число (01000001 в шестнадцатеричной системе счисления это 41). Но если послать это число в память видеоадаптера как символ, то на экране появится буква А (в соответствие с кодировкой ASCII 01000001 соответствует символу А).

Так как информация хранится в памяти в двоичном виде, довольно часто приходится переводить двоичные числа в десятичные или шестнадцатеричные.

Чтобы перевести двоичное число в десятичное, просуммируйте десятичные эквиваленты всех позиций двоичного числа, в которых находится единица. Рассмотрим пример преобразования числа 00001001b:

Рис. 2. Преобразование двоичного числа в десятичное

В конце двоичных чисел принято добавлять «b», в конце шестнадцатеричных − «h», в конце десятичных ничего не добавляют.

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

Рассмотрим пример преобразования двоичного числа 000101100000011110010100b:

Рис. 3. Преобразование двоичного числа в шестнадцатеричное

Каждая позиция шестнадцатеричного числа представляет степень числа 16, что используется при вычислении десятичного значения числа. Для преобразования шестнадцатеричного значения в десятичное необходимо умножить значение каждого разряда на соответствующий эквивалент, а потом их просуммировать. Рассмотрим пример преобразования шестнадцатеричного числа 3BA4h:

Рис. 4. Преобразование шестнадцатеричного числа в десятичное

Выше были рассмотрено преобразование двоичных чисел без знака. Такие числа используют все отведенные им биты для получения значения. Если на число без знака отводится один байт, то максимальное в этом случае значение будет равно 255 (28), если слово, то − 65535 (216).

Байт со знаком для получения значения использует только семь битов, так как старший бит зарезервирован для знака, при этом 0 соответствует положительному числу, а 1 − отрицательному, например:

знаковый бит

Рис. 5. Отображение положительного и отрицательного числа

Чтобы не усложнять процессор, отдельный блок для реализации операции вычитания не делают; эту операцию выполняет также блок суммирования. Перед суммированием отрицательные числа преобразовывают в дополнительные. Это такое число, которое в сумме с исходным дает ноль. Например, десятичное число -10 будет дополнением к 10, так как 10+(-10)=0. Таким образом, вместо операции вычитания А-В процессор суммирует с положительным числом А дополнительное к В: А+(-В). Например, вместо того чтобы вычесть 10 из 20, процессор просто складывает число 10, записанное в дополнительном коде, и 20.

Чтобы получить число в дополнительном коде необходимо сначала инвертировать все биты (поменять нули на единицы и наоборот), а затем прибавить 1:

исходное число 00001010 10

инвертировать биты 11110101 инверсированное число

добавить 1 11110110 -10

Число со знаком из п разрядов может использовать только (п-1) бит для получения значения (см. табл. 1). Например, знаковый байт использует только семь битов. Тогда максимальное число, которое он может хранить равно 127 (27), а минимальное, записанное в дополнительном коде, равно (-128).

Таблица 1. Целые числа со знаком и без знака

Тип хранения

Биты

Диапазон

байт со знаком

7

от -127 до 128

байт без знака

8

от 0 до 255

слово со знаком

15

от -32768 до 32767

слов без знака

16

от 0 до 65536

двойное слово со знаком

31

от -2147483648 до 2147483647

двойное слово без знака

32

от 0 до 4294967296

учетверенное слово со знаком

63

от -9223372036854775808 до 9223372036854775807

учетверенное слово без знака

64

от 0 до 18446744073709551616

Для хранения символьной информации используется схема кодирования символов, которая позволяет преобразовывать символы в числа и наоборот. Наиболее известная из них − ASCII (читается как «аски»), в которой каждому символу присваевается уникальный код, включая контрольные символы, используемые при печати и передачи данных между компьютерами.

Стандартный набор символов ASCII использует только 7 битов для каждого символа. Значения от 0 до 31 заняты служебными кодами, используемыми при печати, передачи информации и выводе на экран. В обычном режиме они не отображаются на экране (см. Приложение 1).

Добавление 8-го разряда позволяет увеличить количество кодов таблицы ASCII до 255. Коды от 128 до 255 представляют собой расширение таблицы ASCII. Эти коды используются для кодирования символов национальных алфавитов, а также символов псевдографики, которые можно использовать, например, для оформления в тексте различных рамок и текстовых таблиц. В Приложении 2 приведена Кодовая таблица 866 – MS-DOS, которой мы и будем пользоваться.

Строка символов размещается в соседних байтах памяти: код первого символа записывается в первом байте, код второго символа − во втором байте и т.д. Например, числовым кодам строки «АВС123» будет соответствовать последовательность значений 41h, 42h, 43h, 31h, 32h и 33h.

Теперь коротко рассмотрим, как в ассемблере выделяется память под переменные. Начнем с выделения самого маленького участка − байта (его вполне достаточно для хранения небольшого числа или одного символа). Выделяется байт с помощью специальной команды компилятору (иначе директивы) db, которая расшифровывается как define byteопределить байт. Например, строка

a db -122

выделяет один байт под переменную а и, кроме этого, помещает в эту ячейку памяти число (-122).

Строка

b db ‘*’

выделяет один байт под переменную b и помещает в эту ячейку памяти символ «*». Заметьте, что сам символ помещают в одинарные или двойные кавычки. Так как каждый символ имеет свой код, то директива

b db 02Ah

полностью эквивалентна предыдущему примеру (см. Приложение 1).

Для выделения памяти под строку так же используют директиву db

string db ‘abcd’

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

string db ‘a’,‘b’,‘с’,‘d’

полностью эквивалентна предыдущему примеру.

Если же строка состоит из повторяющейся последовательности символов, например, «abcdabcdabcd», то можно воспользоваться конструкцией повторения dup:

string db 3 dup (‘a’,‘b’,‘с’,‘d’)

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

с db ?

аналогичным образом выделяется место и под строку

string db ?,?,?,?

Последний пример можно записать короче:

string db 4 dup (?)

Для выделения под переменную большего места − слова, двойного или учетверенного слова, используют соответственно директивы dw, dd и dq. Например,

d dw -1

e dd -1

теперь под переменную d выделено два байта, а под переменную e − восемь.

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