CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Стандартные или упрощенные директивы определения сегментов?
-----------------------------------------------------------------
Теперь, когда вы познакомились и с упрощенными, и со стан-
дартными директивами определения сегментов, возникает вопрос, ка-
кой набор директив определения сегментов следует использовать?
Ответ зависит от типа выполняемого программирования на Ассембле-
ре.
Если вы компонуете модули на Ассемблере с языками высокого
уровня, почти всегда желательно использовать упрощенные директивы
определения сегментов. Эти директивы выполняют всю работу по наи-
менованию сегментов и все функции, связанные с моделью памяти и
организации интерфейса с языками высокого уровня.
Если вы пишете большие автономные программы на Ассемблере,
используя много сегментов и смешанные модели памяти (код ближнего
и дальнего типа и/или данные ближнего и дальнего типа в одной
программе), то вам потребуется использовать стандартные директивы
определения сегментов, что позволит вам полностью управлять типом
сегмента, выравниванием, наименованием сегментов и способом их
комбинирования (сочетания).
Кратко можно сформулировать следующее правило: используйте
упрощенные директивы определения сегментов, пока вы не обнаружи-
те, что вам необходимо получить полное управление определениями
сегментов, которое может обеспечить только стандартное (полное)
определение сегментов.
Выделение данных
-----------------------------------------------------------------
Теперь, когда вы знаете, как создавать сегменты, давайте
рассмотрим, как можно заполнить эти сегменты осмысленными данны-
ми. Сегмент стека проблемы не представляет: там находится стек, а
к стеку вы можете обратиться с помощью инструкций PUSH и POP и
адресоваться через регистр BP. Сегмент кода заполняется инструк-
циями, которые генерируются в соответствии с мнемоникой инструк-
ций вашей программы, поэтому проблемы здесь также нет.
Остается сегмент данных. В Турбо Ассемблере предусмотрено
множество способов определения переменных в сегменте данных, как
инициализируемых некоторым значением, так и неинициализированных.
Чтобы понять, какие данные позволяет вам определять Турбо Ассемб-
лер, мы должны сначала немного рассказать вам основных типах дан-
ных Ассемблера.
Биты, байты и основания
-----------------------------------------------------------------
Основной единицей памяти компьютера является бит. В бите мо-
жет храниться значение 0 или 1. Бит сам по себе не особенно поле-
зен. Процессор 8086 не работает непосредственно с битами, он ра-
ботает с байтами, которые состоят из 8 бит.
Так как бит на самом деле представляет собой цифру с основа-
нием 3, байт содержит 8-разрядное число с основанием 2. Наиболь-
шие возможные числа с основанием 2 - это следующие числа:
2 в степени 0: 1
2 в степени 1: 2
2 в степени 2: 4
2 в степени 3: 8
2 в степени 4: 16
2 в степени 5: 32
2 в степени 6: 64
2 в степени 7: + 128
---
255
Это означает, что в байте может храниться значение в диапа-
зоне от 0 до 255.
В каждом из 8-разрядных регистров процессора 8086 (AL, AH,
BL, CL, CH, DL и DH) храниться ровно 1 байт. В каждой из 1000000
адресуемых ячеек памяти процессора 8086 также может храниться
ровно 1 байт.
Набор символов компьютера PC (который включает в себя строч-
ные и прописные символы, цифры от 0 до 9, специальные графические
символы, научные и специальные символы, а также различные знаки
пунктуации и прочие символы) состоит из ровно 256 символов.
Это число уже знакомо нам, не правда ли? Это не удивительно,
ведь набор символов компьютера РС построен таким образом, что в 1
байте хранится 1 символ.
Байт - это наименьшая единица адресации процессора 8086. В
нем может храниться 1 символ, 1 беззнаковое значение от 0 до 255
или одно значение со знаком в диапазоне от -128 до 127. Ясно, что
байт не подходит для многих задач программирования на Ассемблере,
например, хранения целых значений и значений с плавающей точкой,
а также указателей на память.
Следующая по величине единица памяти процессора 8086 - это
16-разрядное слово. Слово вдвое превосходит по размеру байт (со-
держит 16 бит). Фактически, слово храниться в памяти в виде двух
последовательных байтовых ячеек. Адресное пространство процессора
8086 можно рассматривать, как 500000 слов. Каждый из 16-разрядных
регистров (регистр AX, BX, CX, DX, SI, DI, BP, SP, CS, DS, ES,
SS, IP и регистр флагов) хранит одно слово.
Наибольшие возможные 16-разрядные числа с основанием 2 - это
следующие числа:
2 в степени 0: 1
2 в степени 1: 2
2 в степени 2: 4
2 в степени 3: 8
2 в степени 4: 16
2 в степени 5: 32
2 в степени 6: 64
2 в степени 7: 128
2 в степени 8: 256
2 в степени 9: 512
2 в степени 10: 1024
2 в степени 11: 2048
2 в степени 12: 4096
2 в степени 13: 8182
2 в степени 14: 16384
2 в степени 15: + 32768
-----
65535
Это также представляет собой максимальную величину целого
без знака, что не случайно, так как целые имеют длину 16 бит. Це-
лые со знаком (которые могут принимать значения в диапазоне от
-32768 до +32676) также хранятся в словах.
Так как слова имеют размер 16 бит, они могут адресоваться по
любому смещению в данном сегменте, поэтому значения размером в
слово достаточно велики, чтобы их можно было использовать в ка-
честве указателей памяти. Если вы вспомните, регистры BX, BP, SI
и DI размером в слово используются, как указатели на память.
Значения, хранимые в виде 32-битовых (4-байтовых) элементов,
называются двойными словами. Хотя процессор 8086 не может непос-
редственно работать с 32-битовыми целыми значениями, выполнять
32-разрядные арифметические операции (с помощью двух последова-
тельных 16-разрядных операций) можно с помощью таких инструкций,
как ADC и SBB. Благодаря двойным словам беззнаковые целые могут
принимать значения в диапазоне от 0 до 4294967295, а целые со
знаком - в диапазоне от -2147483648 до +2147483647.
Процессор 8086 может загружать указатель вида "сегмент:сме-
щение" из двойного слова в сегментный регистр и в регистр общего
назначения (с помощью инструкций LDS или LES), но это далеко от
непосредственных операций с двойными словами. В виде двойных слов
хранятся также числа одинарной точности с плавающей точкой (числа
с одинарной точностью занимают 4 байта и могут принимать значения
от 10 в -38 степени до 10 в 38 степени).
Каждое значения с плавающей точкой двойной точности требует
для хранения 8 байт. Такие 64-битовые значения называются четвер-
ными словами. В процессоре 8086 встроенная поддержка четверных
слов отсутствует. Однако арифметический сопроцессор 8087 исполь-
зует четверные слова в качестве базового типа данных. (Числа с
двойной точностью могут принимать значения в диапазоне от 10 в
-308 степени до 10 в 308 степени и иметь точность до 16 цифр.)
Для временных (промежуточных) значений с плавающей точкой
Турбо Ассемблер поддерживает еще один тип данных - элемент данных
длиной 10 байт. Этот 10-байтовый элемент данных (так называемый
временно-вещественный формат) может также использоваться для хра-
нения упакованных двоично-десятичных (или двоично кодированных
десятичных) значений (BCD), в которых в каждом байте хранится две
десятичных цифры.
Стоит заметить, что процессор 8086 хранит значения размером
в слово или двойное слова в памяти, при этом младший байт следует
первым. То есть, если значения размером в слово хранится по адре-
су 0, то в биты 7-0 значения записаны по адресу 0, а биты 15-8 -
по адресу 1 (см. Рис. 5.4).
-----------------------
WordVar --------------------> 0 | 9Fh |
|---------------------|
1 | 19h |
|---------------------|
2 | ? |
|---------------------|
3 | ? |
|---------------------|
4 | ? |
|---------------------|
DwordVar ------------------> 5 | 78h |
|---------------------|
6 | 56h |
|---------------------|
7 | 34h |
|---------------------|
8 | 12h |
|---------------------|
9 | ? |
|---------------------|
| |
. .
. .
Рис. 5.4 Переменная WordVar (размером в слово) содержит зна-
чение 199h, переменная DwordVar (размером в двойное слово) содер-
жит значение 123456h.
Аналогично, если значение размеров в двойное слово хранится
по адресу 5, то биты 7-0 хранятся по адресу 5, биты 15-8 хранятся
по адресу 6, биты 23-16 - по адресу 7, а биты 31-24 по адресу 8.
Это может показаться несколько странным, но именно так работают
все процессоры серии iAPx86.
