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.