Биты, байты и слова

Битом мы условились называть один двоичный разряд, значение которого может быть либо 0, либо 1. Для удобства введем специальные названия для некоторых последовательностей битов.

Группу из восьми бит обычно называют байтом, и в дальнейшем для обозначения 8-битовых данных будет использоваться этот термин. Существует ряд причин, по которым байт имеет специальное название. Элементарная ячейка памяти имеет длину 8 бит. В персональной ЭВМ при каждом обращении к оперативной памяти в микропроцессор пересылается ровно 8 бит данных. Как мы увидим в дальнейшем, некоторые команды микропроцессора 8088 могут реализовать арифметические и логические операции с 8-битовыми данными. Байт является наименьшей совокупностью данных, с которой микропроцессор 8088 может непосредственно манипулировать. С помощью одной команды микропроцессора 8088 можно слодить два 8-битовых числа, но нельзя сложить два 4-битовых числа. Кроме этого, байт используется для представления символов.

Используя отдельный байт, можно представить 256 (28) отдельных элементов, таких, например, как графические символы. В следующем разделе мы рассмотрим набор символов IBM PC.

Так как байт является элементарной ячейкой памяти, то должна быть возможность задавать содержимое отдельных байтов памяти. Работа ассемблера фактически и состоит в задании содержимого рабочей памяти для выполнения программы. Обычно исходная программа на языке ассемблера состоит из команд, которые должны быть выполнены. Тем не менее, в ассемблере имеется специальный механизм записи определенного значения в байт памяти - псевдокоманда определения байта DB. DB не является командой микропроцессора 8088, а служит указанием ассемблеру записать определенные значения в память. Псевдокоманда

DB 23

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

DB 1,2,3,4,

записывает значения от 1 до 4 в четыре последовательных ячейки памяти.

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

DB ?

сообщает ассемблеру, что нужно зарезервировать один байт памяти, не задавая его содержимое. В этом байте может оказаться произвольное значение до тех пор, пока с помощью какой-либо команды в него не будет записано определенное значение. Может также возникнуть необходимость зарезервировать большое число ячеек, например, чтобы выделить область памяти для массива. Это позволяет сделать псевдокоманда

DB 25 DUP (?)

которая зарезервирует 25 байт памяти. В этой псевдокоманде ключевым словом является слово DUP, обозначающее дублирование. Число 25 показывает, сколько раз ассемблер дублирует выполнение команды определения байта. А значение, заключенное в скобки, используется ассемблером как начальное значение, записываемое в этом месте памяти. В данном случае это значение не определено. Если нужно задать одно и то же начальное значение на каком-то участке памяти, то в этом случае, например, с помощью оператора

DB 17 DUP (31)

резервируется 17 байт со значением 31 в каждой ячейке. Соответственно, с помощью оператора

DB 30 DUP (1,2,3,4,5)

резервируется 30 байт со значениями от 1 до 5 в первых пяти байтах. В следующие пять байт записываются те же значения от 1 до 5 и т.д. Ассемблер будет повторять выборку значений из скобок, пока не будет произведена запись значений во все 30 байт.

Иногда бывает необходимо обратиться к последовательности битов, меньшей, чем байт. Обычно это последовательность длиной 4 бит. С помощью четырех бит можно представить 10 десятичных цифр. Для обозначения 4-битовой последовательности мы будем пользоваться термином полубайт. Этот широко распространенный термин позволяет именовать данные, меньшие, чем байт.

Термин "слово" используется программистами в не общепринятом смысле. Применительно к ЭВМ слово - это наибольшая последовательность битов, которую ЭВМ может обрабатывать как единое целое. В системе IBM/370 слово имеет размер 32 бит, а в микропроцессоре 8088 - 16 бит. Поэтому до тех пор, пока не указан конкретный тип ЭВМ, термин "слово" мало о чем говорит.

Длина слова микропроцессора 8088 - 16 бит. Это число определяется каналами передачи данных внутри микропроцессора. В микропроцессоре 8088 арифметические и логические операции над значениями вплоть до 16 бит могут быть реализованы одной командой. Имеются команды, которые оперируют меньшими числами, например, команда сложения двух 8-битовых чисел. Имеется несколько команд, которые позволяют оперировать отдельными битами числа. Однако для сложения двух 32-битовых чисел требуется две команды, каждая из которых обеспечивает сложение 16 бит. Набольшее число, над которым можно выполнять простейшие операции типа сложения, - это и есть длина машинного слова данной ЭВМ.

Аналогично команде определения байта памяти в языке ассемблера имеется команда определения слова памяти, и соответствующий оператор обозначается DW. Первый из приведенных на рис.2.10 операторов DW записывает в память 16-битовое значение, равное 1234H. Как и в случае с байтами, для задания в памяти больших областей, состоящих из слов, можно использовать оператор DUP. И точно также для обозначения неопределенных областей используется операнд "?".

Одна из особенностей микропроцессора 8088 состоит в способе записи слов в память. Из рис.2.10 видно, что хотя мы определили слово со значением 1234H, ассемблер записывает его в память, как значение 3412H (по крайней мере выглядит это так). Посмотрим, почему.

Предположим, что слово 1234H записано в ячейки 100 и 101. Структура микропроцессора 8088 такова, что ассемблер записывает значение 34H в ячейку 100, а значение 12H - в ячейку 101. Проще всего запомнить это так: ассемблер записывает младший байт (байт младших разрядов) слова в ячейку с меньшим адресом, а старший байт (байт старших разрядов) слова - в ячейку со старшим адресом. На рис.2.11 показано содержимое памяти после того, как ассемблер записал туда данные. На начальном этапе работы с микропроцессором 8088 вам будет казаться, что в памяти все записывается наоборот. К счастью, пока в программе не присутствуют одновременно операции побайтовой и пословной обработки содержимого одной и той же ячейки памяти, можно не беспокоиться по поводу этого кажущегося "переключения" байтов. Программа может обрабатывать слова без каких-либо затруднений, так как микропроцессор 8088 всегда обеспечит нужный порядок. И только когда нужно обратиться к конкретному байту слова, придется учитывать фактический порядок записи слов в память. В листинге программы формат слов выделяется. Это достигается за счет того, что в объектном коде слова представляются ассемблером как слова, а не как отдельные байты, что соответствовало бы обратной записи слова. Слово может быть идентифицировано, поскольку оно представляется четырьмя шестнадцатеричными символами без пробелов.

Существует еще один формат данных, который широко используется в программах на языке ассемблера для микропроцессора 8088. Это - двойное слово, 32-битовое значение. Двойное слово используется в программах для хранения значения адреса или очень большого числа. Чтобы задать область, содержащую значение двойного слова, оператор языка ассемблера

DD значение

выделяет 4 байта памяти. DD - это код операции определения двойного слова. Аналогично оператору DW, ассемблер записывает значение самого младшего байта в ячейку с наименьшим адресом, а значение самого старшего байта - в ячейку с наибольшим адресом. В том же порядке записываются значения двух промежуточных байтов. И так же, как в случае оператором DB и DW, можно использовать параметр DUP и, если содержимое зарезервированной области не определено, в качестве операнда - символ "?".

Существуют и другие форматы данных, которые может генерировать ассемблер. Мы вернемся к рассмотрению соответствующих операторов после того, как обсудим характеристики Макроассемблера и арифметического сопроцессора 8087. Не рассмотренные пока структуры данных используются главным образом для представления очень больших чисел в арифметическом сопроцессоре (см.гл.7), либо для определения в этих программах собственных форматов данных.

Хостинг от uCoz