Logo Спонсор сайта — Хостинг Fornex.com Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
VPS/VDS за 1 евро!

vCore x1, 1 GB RAM ECC, 15 GB SSD (RAID 10), Port 1 Gbps, Трафик ∞, Виртуализатор KVM.

Выбор стран: Нидерланды, Молдова и Россия!

Больше чем хостинг: полный спектр услуг для сайта и сервера.

- Виртуальный хостинг: перенос сайта, анализ безопасности и 1 месяц бесплатно
- Калькулятор VPS: бери столько, сколько нужно
- Партнерам — постоянный доход
- 8-800-200-25-11 круглосуточно

Бесплатный конструктор сайтов и Landing Page

Хостинг с DDoS защитой от 2.5$ + Бесплатный SSL и Домен

SSD VPS в Нидерландах под различные задачи от 2.6$

Сверхбыстрый хостинг от 69 р./мес., VPS от 299 р./мес.

Бесплатно: администрирование + ISPmanager + DDoS защита + SSL + 7 дней тестовый период

Скидка 50% на первый месяц VPS и хостинга по промокоду CITFORUM

Глава 5. Использование выражений и значений идентификаторов

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


Константы

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

Числовые константы

Числовые константы в Турбо Ассемблере всегда начинаются с цифры (0-9) и содержат произвольное число алфавитно-цифровых символов. Фактическое значение константы зависит от основания, которое вы выбираете для ее интерпретации. В Турбо Ассемблере можно использовать двоичное, восьмеричное, десятичное или шест- надцатиричное основание, что показано в приведенной ниже таблице: Основания Таблица 5.1 ------------------------T---------------------------------------¬ ¦ Основание ¦ Допустимые цифры ¦ +-----------------------+---------------------------------------+ ¦двоичное ¦ 0 1 ¦ ¦восьмеричное ¦ 0 1 2 3 4 5 6 7 ¦ ¦десятичное ¦ 0 1 2 3 4 5 6 7 8 9 ¦ ¦шестнадцатиричное ¦ 0 1 2 3 4 5 6 7 8 9 A B C D E F ¦ L-----------------------+---------------------------------------- Заметим, что в шестнадцатиричных константах вы можете ис- пользовать буквы как в верхнем, так и в нижнем регистре. Турбо Ассемблер определяет основание числовой константы, проверяя сначала последний ее символ. Символы, используемые для задания основания при интерпретации константы, приведены в следу- ющей таблице: Символы, определяющие основания Таблица 5.2 ---------------------T------------------------------------------¬ ¦ Символ ¦ Основание ¦ +--------------------+------------------------------------------+ ¦ B ¦ двоичное ¦ ¦ O ¦ восьмеричное ¦ ¦ Q ¦ восьмеричное ¦ ¦ D ¦ десятичное ¦ ¦ H ¦ шестнадцатиричное ¦ L--------------------+------------------------------------------- Для задания основания числа можно использовать символы как верхнего, так и нижнего регистра. Последним символом числовой константы должно быть одно из этих значений. Если последним сим- волом числовой константы не является один из этих символов, Тур- бо Ассемблер будет для интерпретации константы использовать теку- щее назначенное по умолчанию основание. Доступные числовые конс- танты и их значения приведены в следующей таблице: Числовые константы Таблица 5.3 -----------------------T----------------------------------------¬ ¦Числовая константа ¦ Значение ¦ +----------------------+----------------------------------------+ ¦ 77d ¦ 77 десятичное ¦ ¦ 77h ¦ 77 шестнадцатиричное ¦ ¦ ffffh ¦ недопустимо, не начинается с цифры ¦ ¦ 0ffffh ¦ FFFF шестнадцатиричное ¦ ¦ 88 ¦ интерпретация зависит от текущего ис- ¦ ¦ ¦ пользуемого по умолчанию основания ¦ L----------------------+-----------------------------------------

Изменение используемого по умолчанию основания

Для изменения текущего используемого по умолчанию основания вы можете использовать директивы RADIX или .RADIX. В режиме Ideal используется следующий синтаксис: RADIX выражение а в режиме MASM: .RADIX выражение где "выражение" должно принимать значение 2 (двоичное), 8 (вось- меричное), 10 (десятичное) или 16 (шестнадцатиричное). Турбо Ас- семблер предполагает, что во время обработки директивы RADIX те- кущим основанием по умолчанию является основание 10.

Строковые константы

Строковые константы всегда начинаются с одиночной или двой- ной кавычки и завершаются соответствующей кавычкой. Турбо Ассемб- лер преобразует заключенные в кавычки символы в значения ASCII. Иногда желательно использовать кавычку в самой строковой константе. Для этого в качестве одной кавычки используйте пару совпадающих символов кавычек, например: 'It''s represent' It's

Идентификаторы

Идентификатор представляет значение, которое может быть пе- ременной, меткой адреса или операндом ассемблируемой инструкции и директивы.

Имена идентификаторов

Имена идентификаторов представляют собой сочетание букв (в верхнем и нижнем регистре), цифр и специальных символов. Имена идентификаторов не могут начинаться с цифры. Турбо Ассемблер мо- жет интерпретировать имена идентификаторов с различием регистра символов или без него. Различимостью регистра символов можно уп- равлять с помощью параметров командной строки Турбо Ассемблера /ML, /MU и /MX. Имена идентификаторов могут иметь в длину до 255 символов. По умолчанию имена идентификаторов являются значащими до 32 сим- волов. Для изменения числа значащих символов в имени идентифика- тора вы можете использовать параметр командной строки /MV. Примечание: Об использовании параметров командной строки рассказывается в Главе 2. В имени идентификатора можно использовать символ подчеркива- ния (_), знак вопроса (?), знак доллара ($) и символ @. В режиме MASM (и только в нем) в качестве первого символа имени вы можете использовать точку (.). Однако легко спутать точку в начале иден- тификатора с операцией точки (которая используется для выделения элемента структуры), поэтому лучше не использовать ее в именах идентификаторов.

Типы идентификаторов

Каждый идентификатор имеет тип, который описывает его харак- теристики и связанную с ним информацию. Тип задается способом оп- ределения идентификатора. Например, вы можете определить иденти- фикатор, представляющий числовое выражение, текстовую строку, имя процедуры или переменную. Типы идентификаторов, поддерживаемых Турбо Ассемблером, перечислены в Таблице 5.4. Типы идентификаторов Таблица 5.4 ----------------------------T------------------------------------¬ ¦ Тип идентификатора ¦ Описание ¦ +---------------------------+------------------------------------+ ¦ адрес ¦ Адрес. Подтипами данных являются ¦ ¦ ¦ типы UNKNOWN, BYTE, WORD, DWORD, ¦ ¦ ¦ PWORD, QWORD, TBYTE и адрес струк- ¦ ¦ ¦ туры или таблицы с указанным име- ¦ ¦ ¦ нем. Подтипами кода являются ¦ ¦ ¦ SHORT, NEAR, FAR. ¦ ¦ ¦ ¦ ¦ ¦ ¦ ¦ текстовая макрокоманда ¦ Текстовая строка. ¦ ¦ ¦ ¦ ¦ псевдоним ¦ Эквивалентный идентификатор. ¦ ¦ ¦ ¦ ¦ числовое выражение ¦ Значение числового выражения. ¦ ¦ ¦ ¦ ¦ макрокоманда из ¦ Несколько текстовых строк с пус- ¦ ¦ нескольких строк ¦ тыми аргументами. ¦ ¦ ¦ ¦ ¦ структура/объединение ¦ Тип данных структуры или объеди- ¦ ¦ ¦ нения. ¦ ¦ ¦ ¦ ¦ таблица ¦ Табличный тип данных. ¦ ¦ ¦ ¦ ¦ элемент структуры/ ¦ Элемент структуры или таблицы. ¦ ¦ таблицы ¦ ¦ ¦ ¦ ¦ ¦ запись ¦ Данные типа записи. ¦ ¦ ¦ ¦ ¦ поле записи ¦ Поле записи. ¦ ¦ ¦ ¦ ¦ перечисление ¦ Перечислимый тип данных. ¦ ¦ ¦ ¦ ¦ сегмент ¦ Сегмент. ¦ ¦ ¦ ¦ ¦ группа ¦ Группа. ¦ ¦ ¦ ¦ ¦ тип ¦ Названный тип. ¦ L---------------------------+-------------------------------------

Адресные подтипы данных

Подтипы идентификаторов описывают идентификатор, представля- ющий адрес байта, слова и т.д. Простые адресные подтипы, которые предусмотрены в Турбо Ассемблере, приведены в Таблице 5.5. Адресные подтипы Таблица 5.5 --------------------T-------------------------------------------¬ ¦ Выражение типа ¦ Значение ¦ +-------------------+-------------------------------------------+ ¦ UNKNOWN ¦ Неизвестный или неопределенный адресный ¦ ¦ ¦ подтип. ¦ ¦ ¦ ¦ ¦ BYTE ¦ Адрес, описывающий байт. ¦ ¦ ¦ ¦ ¦ WORD ¦ Адрес, описывающий слово. ¦ ¦ ¦ ¦ ¦ DWORD ¦ Адрес, описывающий 4-байтовую величину. ¦ ¦ ¦ ¦ ¦ PWORD или FWORD ¦ Адрес, описывающий 6-байтовую величину. ¦ ¦ ¦ ¦ ¦ QWORD ¦ Адрес, описывающий 8-байтовую величину. ¦ ¦ ¦ ¦ ¦ TBYTE ¦ Адрес, описывающий 10-байтовую величину. ¦ ¦ ¦ ¦ ¦ SHORT ¦ Адрес, описывающий короткий адрес метки/ ¦ ¦ ¦ процедуры. ¦ ¦ ¦ ¦ ¦ NEAR ¦ Адрес, описывающий ближний адрес метки/ ¦ ¦ ¦ процедуры. ¦ ¦ ¦ ¦ ¦ FAR ¦ Адрес, описывающий дальний адрес метки/ ¦ ¦ ¦ процедуры. ¦ ¦ ¦ ¦ ¦ PROC ¦ Адрес, описывающий ближний или дальний ¦ ¦ ¦ адрес метки/процедуры, в зависимости от ¦ ¦ ¦ текущей модели. ¦ ¦ ¦ ¦ ¦ DATAPTR ¦ Адрес, описывающий слово, двойное слово ¦ ¦ ¦ или величину pword, в зависимости от те- ¦ ¦ ¦ кущей выбранной модели. ¦ ¦ ¦ ¦ ¦ CODEPTR ¦ Адрес, описывающий слово, двойное слово ¦ ¦ ¦ или величину pword, в зависимости от те- ¦ ¦ ¦ кущей выбранной модели. ¦ ¦ ¦ ¦ ¦ имя структуры/ ¦ Адрес, описывающий экземпляр названной ¦ ¦ объединения ¦ структуры или объединения. ¦ ¦ ¦ ¦ ¦ имя таблицы ¦ Адрес, описывающий экземпляр указанной ¦ ¦ ¦ таблицы. ¦ ¦ ¦ ¦ ¦ имя записи ¦ Адрес, описывающий экземпляр указанной ¦ ¦ ¦ записи (байт, слово или двойное слово). ¦ ¦ ¦ ¦ ¦ имя перечисления ¦ Адрес, описывающий экземпляр перечислимо- ¦ ¦ ¦ го типа данных. ¦ ¦ ¦ ¦ ¦ имя типа ¦ Адрес, описывающий экземпляр указанного ¦ ¦ ¦ типа. ¦ ¦ ¦ ¦ ¦ TYPE выражение ¦ Адрес, описывающий элемент, подтип кото- ¦ ¦ ¦ рого является адресом подтипа выражения ¦ ¦ ¦ (только для режима Ideal). ¦ L-------------------+--------------------------------------------

Описание сложного адресного подтипа

Некоторые директивы позволяют вам описывать сложные адресные подтипы. Эти выражения типов аналогичны тем, которые используют- ся в языке Си, поскольку они представляют несколько уровней кос- венности указателя. Например, сложное выражение типа: PTR WORD представляет указатель на слово. (Размер указателя зависит от размера модели сегментации, которую вы выбираете с помощью дирек- тивы MODEL.) Сводный синтаксис сложных адресных подтипов приведен в Таб- лице 5.6. Сложные адресные подтипы Таблица 5.6 -------------------------------------T--------------------------¬ ¦ Синтаксис ¦ Значение ¦ +------------------------------------+--------------------------+ ¦ простой_адресный_подтип ¦ Подтип заданного адреса. ¦ ¦ ¦ ¦ ¦ [раст]PTR[сложный_адресный_подтип]¦ Указатель на заданный ¦ ¦ ¦ сложный адресный подтип, ¦ ¦ ¦ размер которого опреде- ¦ ¦ ¦ ляется текущей директи- ¦ ¦ ¦ вой MODEL или заданным ¦ ¦ ¦ расстоянием (если они ¦ ¦ ¦ присутствуют). ¦ L------------------------------------+--------------------------- Необязательный параметр расстояния вы можете описать следую- щим путем: Синтаксис расстояния Таблица 5.7 --------------------T-------------------------------------------¬ ¦ Синтаксис ¦ Значение ¦ +-------------------+-------------------------------------------+ ¦ NEAR ¦ Используется ближний указатель, который ¦ ¦ ¦ может быть 16 или 32-разрядным, в зависи- ¦ ¦ ¦ мости от текущей модели. ¦ ¦ ¦ ¦ ¦ FAR ¦ Используется дальний указатель, который ¦ ¦ ¦ может быть 32 или 48-разрядным, в зависи- ¦ ¦ ¦ мости от текущей модели. ¦ ¦ ¦ ¦ ¦ SMALL NEAR ¦ Используется 16-разрядный указатель ¦ ¦ ¦ (только для процессоров 80386 и 80486). ¦ ¦ ¦ ¦ ¦ LARGE NEAR ¦ Используется 32-разрядный указатель ¦ ¦ ¦ (только для процессоров 80386 и 80486). ¦ ¦ ¦ ¦ ¦ SMALL FAR ¦ Используется 32-разрядный дальний указа- ¦ ¦ ¦ тель (только для процессоров 80386 и ¦ ¦ ¦ 80486). ¦ ¦ ¦ ¦ ¦ LARGE FAR ¦ Используется 48-разрядный дальний указа- ¦ ¦ ¦ тель (только для процессоров 80386 и ¦ ¦ ¦ 80486). ¦ L-------------------+-------------------------------------------- Тип указываемого объекта в комплексных ссылочных типах не является строго обязательным. Турбо Ассемблеру нужно знать только размер типа. Таким образом, в сложных ссылочных типах (но не в простых типах) допускаются опережающие ссылки.

Выражения

Использование выражений позволяет вам получать модульный код, поскольку вы можете символически представлять в программе значения. Турбо Ассемблер выполняет все повторные вычисления, не- обходимые при изменениях (и не требует этого от вас). В присваиваниях Турбо Ассемблер использует стандартное ин- фиксное обозначение. Выражения могут содержать операнды и унарные или бинарные операции. Унарная операция помещается перед одиноч- ным операндом; бинарные операции помещаются между двумя операнда- ми. Примеры простых операций показаны в Таблице 5.8. Простые выражения Таблица 5.8 ---------------------T------------------------------------------¬ ¦ Выражение ¦ Что получается при вычислении ¦ +--------------------+------------------------------------------+ ¦ 5 ¦ константа 5 ¦ ¦ -5 ¦ константа -5 ¦ ¦ 4+3 ¦ константа 7 ¦ ¦ 4*3 ¦ константа 12 ¦ ¦ 4*3+2*1 ¦ константа 14 ¦ ¦ 4*(3+2)*1 ¦ константа 21 ¦ L--------------------+------------------------------------------- В Приложении B содержится полная грамматика в форме Бэку- са-Наура, используемая при синтаксическом анализе выражений в режимах MASM и Ideal. Эта грамматика последовательно описывает синтаксис выражений Турбо Ассемблера, а также старшинство опера- ций.

Точность в выражениях

Турбо Ассемблер в режиме Ideal всегда использует 32-разряд- ную арифметику. В режиме MASM Турбо Ассемблер использует 16- или 32-разрядную арифметику, в зависимости от выбора процессора 80386. Таким образом, некоторые выражения, в зависимости от того, какой процессор выбирается, могут давать разные результаты. Нап- ример, при вычислении: (1000h * 1000h) / 1000h получается 1000h при выборе процессора 80386 или 0 при выборе процессоров 8086, 80186 или 80286.

Константы в выражениях

В качестве операндов в выражениях вы можете использовать константы, например: mov ax,5 ; "5" - это операнд-константа

Идентификаторы в выражениях

Когда вы используете в выражении идентификатор, возвращаемое значение зависит от типа идентификатора. Вы можете использовать идентификатор сам по себе или в сочетании с определенными унарны- ми операциями, которые созданы для выделения другой информации из величины, представляемой идентификатором.

Регистры

Имена регистров представляют регистры процессоров семейства 89086 и могут использоваться в составе выражения, например: 5+ax+7 При вычислении данного выражения получается значение ax+12, так как AX - это зарезервированный в Турбо Ассемблере идентифи- катор регистра. Идентификаторы регистров перечислены в следующем списке: 8086 AX, BX. CX, DX, SI, DI, DP, CS, DS, ES, SS 80186,80286 то же, что и для 8086 80386 регистры 8086, плюс EAX, EBX, ECX, EDX, ESI EDI, EBP, PS, GS, CR0, CR3, CR3, DR0, DR1, DR@, DR#, DR6, DR7 80486 регистры процессора 80386, плюс TR3, TR4, TR5

Стандартные значения идентификаторов

Некоторые идентификаторы всегда представляют конкретные зна- чения, и для того, чтобы их использовать, определения не требует- ся. Эти идентификаторы и их значения перечислены в следующей таблице: Стандартные идентификаторы Таблица 5.9 ------------------------T---------------------------------------¬ ¦ Идентификатор ¦ Значение ¦ +-----------------------+---------------------------------------+ ¦ $ ¦ Значение текущего счетчика адре- ¦ ¦ ¦ са программы. ¦ ¦ NOTHING ¦ 0 ¦ ¦ ? ¦ 0 ¦ ¦ UNKNOWN ¦ 0 ¦ ¦ BYTE ¦ 1 ¦ ¦ WORD ¦ 2 ¦ ¦ DWORD ¦ 4 ¦ ¦ PWORD ¦ 6 ¦ ¦ FWORD ¦ 6 ¦ ¦ QWORD ¦ 8 ¦ ¦ TBYTE ¦ 10 ¦ ¦ ¦ ¦ ¦ NEAR ¦ 0ffffh ¦ ¦ FAR ¦ 0fffeh ¦ ¦ PROC ¦ 0ffffh или 0fffeh, в зависимос- ¦ ¦ ¦ ти от текущей модели. ¦ ¦ ¦ ¦ ¦ CODEPTR ¦ 2 или 4, в зависимости от теку- ¦ ¦ ¦ щей модели. ¦ ¦ DATAPTR ¦ 2 или 4, в зависимости от теку- ¦ ¦ ¦ щей модели. ¦ L-----------------------+----------------------------------------

Значения простых идентификаторов

Турбо Ассемблер возвращает для идентификаторов, которые ис- пользуются сами по себе, следующие значения: Значения идентификаторов, используемых непосредственно Таблица 5.10 --------------------------T-------------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------+-------------------------------------+ ¦ имя_адреса ¦ Возвращает адрес. ¦ ¦ ¦ ¦ ¦ имя_числового_выражения ¦ Возвращает значение числового выра- ¦ ¦ ¦ жения. ¦ ¦ ¦ ¦ ¦ имя_таблицы | ¦ Возвращает значение по умолчанию ¦ ¦ имя_элемента_таблицы ¦ элемента таблицы, заданное в опре- ¦ ¦ ¦ делении таблицы. ¦ ¦ ¦ ¦ ¦ структура/ ¦ Возвращает смещение элемента в таб- ¦ ¦ имя_элемента_таблицы ¦ лице или структуре (только в режи- ¦ ¦ ¦ ме MASM). ¦ ¦ ¦ ¦ ¦ имя_записи ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ зарезервированные для представления ¦ ¦ ¦ битовых полей в определении записи, ¦ ¦ ¦ равны 1, а остальные равны 0. ¦ ¦ ¦ ¦ ¦ имя_записи <.> ¦ Возвращает начальное значение эк- ¦ ¦ ¦ земпляра записи, которое имела бы ¦ ¦ ¦ эта запись, если бы она описывалась ¦ ¦ ¦ с текстом, заключенном в угловые ¦ ¦ ¦ скобки (подробности содержатся в ¦ ¦ ¦ Главе 12). ¦ ¦ ¦ ¦ ¦ имя_записи [.] ¦ Аналогично предыдущему. ¦ ¦ ¦ ¦ ¦ имя_поля_записи ¦ Возвращает число бит, на которое ¦ ¦ ¦ смещена запись от младшего бита за- ¦ ¦ ¦ писи (значение сдвига). ¦ ¦ ¦ ¦ ¦ имя_перечисления ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ требуемые для представления макси- ¦ ¦ ¦ мального значения в определении пе- ¦ ¦ ¦ речисления равны 1, а остальные ¦ ¦ ¦ равны 0. ¦ ¦ ¦ ¦ ¦ имя_сегмента ¦ Возвращает значение сегмента. ¦ ¦ ¦ ¦ ¦ имя_группы ¦ Возвращает значение группы. ¦ ¦ ¦ ¦ ¦ имя_структуры/ ¦ Возвращает размер в байтах структу- ¦ ¦ объединения ¦ ры или объединения, но только в том ¦ ¦ ¦ случае, если этот размер равен 1, 2 ¦ ¦ ¦ или 4; в противном случае возвраща- ¦ ¦ ¦ ется 0. ¦ ¦ ¦ ¦ ¦ имя_типа ¦ Если тип определяется как синоним ¦ ¦ ¦ структуры или объединения, то возв- ¦ ¦ ¦ ращаемое значение то же, что и у ¦ ¦ ¦ структуры или объединения. В про- ¦ ¦ ¦ тивном случае возвращается размер ¦ ¦ ¦ типа (с 0ffffh для меток short и ¦ ¦ ¦ near и 0fffeh для меток far). ¦ L-------------------------+-------------------------------------- Все другие типы идентификаторов возвращают значение 0. Заметим, что когда в выражении вы используете имя текстовой макрокоманды, Турбо Ассемблер подставляет вместо идентификатора текстовой макрокоманды значение текстовой макрокоманды. Аналогич- но, когда вы используете имя псевдонима, Турбо Ассемблер подстав- ляет вместо идентификатора псевдонима значение идентификатора, которое представляет псевдоним.

Унарная операция LENGTH

Унарная операция LENGTH возвращает информацию о счетчике или числе величин, представляющих идентификатор. Возвращаемое факти- ческое значение зависит от типа идентификатора, что показано в приведенной ниже таблице: Значения, возвращаемые операцией LENGTH Таблица 5.11 --------------------------------T-------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------------+-------------------------------+ ¦ LENGTH имя_адреса ¦ Возвращает счетчик элементов, ¦ ¦ ¦ выделяемых при определении ¦ ¦ ¦ имени адреса. ¦ ¦ ¦ ¦ ¦ LENGTH имя_элемента_структуры/¦ Возвращает счетчик элементов, ¦ ¦ объединения ¦ выделенных при определении ¦ ¦ ¦ элемента (только режим MASM). ¦ L-------------------------------+-------------------------------- При применении ее ко всем другим типам идентификаторов опе- рация LENGTH возвращает значение 1. Приведем некоторые примеры использования операции LENGTH: MSG DB "Hello" array DW 10 DUP (4 DUP (1),0) numbrs DD 1,2,3,4 lmsg = LENGTHG msg ; =1, нет операции DUP larray = LENGTH nsg ; =10, счетчик повторения DUP lnumbrs = LENGTH numbrs ; =1, нет операции DUP Унарная операция SIZE Унарная операция SIZE возвращает информацию о размере выде- ленного элемента данных. Возвращаемое значение зависит от типа заданного идентификатора. Список доступных для операции SIZE зна- чений приведен в следующей таблице: Значения, возвращаемые операцией SZIE Таблица 5.12 ------------------------------T---------------------------------¬ ¦ Выражение ¦ Значение ¦ +-----------------------------+---------------------------------+ ¦ SIZE имя_адреса ¦ В режиме Ideal возвращается ¦ ¦ ¦ фактическое число байт, выде- ¦ ¦ ¦ ленных для переменных данных. ¦ ¦ ¦ В режиме MASM возвращается ¦ ¦ ¦ размер подтипа имя_адреса ¦ ¦ ¦ (UNKNOWN=0, BYTE=1, WORD=2, ¦ ¦ ¦ DWORD=4, PWORD=FWORD=6, QWORD ¦ ¦ ¦ =8, TBYTE=10, SHORT=NEAR= ¦ ¦ ¦ 0ffffh, FAR=0fffeh, адрес ¦ ¦ ¦ структуры = размеру структу- ¦ ¦ ¦ ры), умноженный на значение ¦ ¦ ¦ LENGTH имя_адреса. ¦ ¦ SIZE имя_структуры/ ¦ Возвращает число байт, требу- ¦ ¦ объединения ¦ емых для представления струк- ¦ ¦ ¦ туры или объединения. ¦ ¦ SIZE имя_таблицы ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ таблицы. ¦ ¦ SIZE имя_элемента_таблицы/ ¦ Возвращает величину TYPE имя ¦ ¦ структуры ¦ _элемента_таблицы/структуры* ¦ ¦ ¦ LENGTH имя_элемента_таблицы/ ¦ ¦ ¦ объединения (только для ре- ¦ ¦ ¦ жима MASM). ¦ ¦ SIZE имя_записи ¦ Возвращает число байт, не- ¦ ¦ ¦ обходимых для представления ¦ ¦ ¦ общего числа бит, зарезерви- ¦ ¦ ¦ рованных в определении запи- ¦ ¦ ¦ си: 1, 2 или 4. ¦ ¦ SIZE имя_перечисления ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ максимального значения, при- ¦ ¦ ¦ сутствующего в перечислении: ¦ ¦ ¦ 1, 2 или 4. ¦ ¦ SIZE имя_сегмента ¦ Возвращает размер сегмента ¦ ¦ ¦ в байтах. ¦ ¦ SIZE имя_типа ¦ Возвращает число байт, необ- ¦ ¦ ¦ ходимых для представления ¦ ¦ ¦ названного типа, при этом ¦ ¦ ¦ ближние и дальние метки воз- ¦ ¦ ¦ вращают значение 0ffffh, а ¦ ¦ ¦ дальние - 0fffeh. ¦ L-----------------------------+---------------------------------- При применении ко всем другим типам идентификаторов операция SIZE возвращает значение 0.

Унарная операция WIDTH

Унарная операция WIDTH возвращает размер в битах поля запи- си. Это значение зависит от типа идентификатора. Эти типы иденти- фикаторов показаны в приведенной ниже таблице. Для всех других типов операцию WIDTH использовать не допускается. Значения WIDTH Таблица 5.13 --------------------------T-------------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------+-------------------------------------+ ¦ WIDTH имя_записи ¦ Возвращает общее число бит, заре-¦ ¦ ¦ зервированных в определении записи.¦ ¦ ¦ ¦ ¦ WIDTH имя_поля_записи ¦ Возвращает число бит, зарезервиро-¦ ¦ ¦ ванных для поля в определении запи-¦ ¦ ¦ си. ¦ ¦ ¦ ¦ ¦ WIDTH имя_перечисления ¦ Возвращает число бит, необходимых ¦ ¦ ¦ для представления максимального ¦ ¦ ¦ значения в определении enum. ¦ L-------------------------+--------------------------------------

Унарная операция MASK

Унарная операция MASK создает маску на основе битового поля, в котором биты в возвращаемом значении устанавливаются в 1 и со- ответствуют битам в поле, которое представляет идентификатор. Возвращаемое значение зависит от типа идентификатора, что показа- но в приведенной ниже таблице. Заметим, что для всех других иден- тификаторов использовать операцию MASK не разрешается. Значения, возвращаемые MASK Таблица 5.14 --------------------------T-------------------------------------¬ ¦ Выражение ¦ Значение ¦ +-------------------------+-------------------------------------+ ¦ MASK имя_записи ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для представления ¦ ¦ ¦ битовых полей в определении записи, ¦ ¦ ¦ равны 1, а остальные равны 0. ¦ ¦ ¦ ¦ ¦ MASK имя_поля_записи ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для поля в определе-¦ ¦ ¦ нии записи, равны 1, а остальные ¦ ¦ ¦ равны 0. ¦ ¦ ¦ ¦ ¦ MASK имя_перечисления ¦ Возвращает маску, в которой биты, ¦ ¦ ¦ резервированные для представления ¦ ¦ ¦ максимального значения в определе- ¦ ¦ ¦ нии перечисления, равны 1, а ос- ¦ ¦ ¦ тальные равны 0. ¦ L-------------------------+--------------------------------------

Общие арифметические операции

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

Простые арифметические операции

Турбо Ассемблер поддерживает простые арифметические опера- ции. которые приведены в следующей таблице: Простые арифметические операции Таблица 5.15 -------------------------------T--------------------------------¬ ¦ Выражение ¦ Значение ¦ +------------------------------+--------------------------------+ ¦ +выражение ¦ Выражение. ¦ ¦ ¦ ¦ ¦ -выражение ¦ Отрицание выражения. ¦ ¦ ¦ ¦ ¦ выражение_1 + выражение_2 ¦ Выражение_1 плюс выражение_2. ¦ ¦ ¦ ¦ ¦ выражение_1 - выражение_2 ¦ Выражение_1 минус выражение_2. ¦ ¦ ¦ ¦ ¦ выражение_1 * выражение_2 ¦ Выражение_1, умноженное на вы- ¦ ¦ ¦ ражение_2. ¦ ¦ ¦ ¦ ¦ выражение_1 / выражение_2 ¦ Выражение_1, деленное на выра- ¦ ¦ ¦ жение_2 (используются целые ¦ ¦ ¦ числа со знаком). Выражение_2 ¦ ¦ ¦ не может быть нулевым или пре- ¦ ¦ ¦ вышать по размеру 16 бит. ¦ ¦ ¦ ¦ ¦ выражение_1 MOD выражение_2 ¦ Остаток от деления выражения_1 ¦ ¦ ¦ на выражение_2. Применяются те ¦ ¦ ¦ же правила, что и при делении. ¦ L------------------------------+---------------------------------

Логические арифметические операции

Логические арифметические операции позволяют вам выполнять операции булевской алгебры. Каждая из этих операций выполняется поразрядно, то есть, логическая операция выполняется по одному биту. Логические операции приведены в следующей таблице. Логические арифметические операции Таблица 5.16 ------------------------------T---------------------------------¬ ¦ Выражение ¦ Значение ¦ +-----------------------------+---------------------------------+ ¦ NOT выражение ¦ Поразрядное дополнение выраже- ¦ ¦ ¦ ния. ¦ ¦ ¦ ¦ ¦ выражение_1 AND выражение_2 ¦ Поразрядная операция "И". ¦ ¦ ¦ ¦ ¦ выражение_1 OR выражение_2 ¦ Поразрядная операция "ИЛИ". ¦ ¦ ¦ ¦ ¦ выражение_1 XOR выражение_2 ¦ Поразрядная операция "исключа- ¦ ¦ ¦ ющее ИЛИ". ¦ L-----------------------------+----------------------------------

Поразрядные операции сдвига

Поразрядные операции сдвига смещают значения вправо или влево на фиксированное число бит. Вы можете использовать их для быстрого выполнения операций умножения или деления или для досту- па к битовому полю в значении. В следующей таблице приведен спи- сок операций сдвига. Логические операции сдвига Таблица 5.17 ------------------------------T---------------------------------¬ ¦ Выражение ¦ Значение ¦ +-----------------------------+---------------------------------+ ¦ выражение_1 SHL выражение_2 ¦ Выражение_1 сдвигается влево на ¦ ¦ ¦ число бит, заданных выражением_ ¦ ¦ ¦ 2 (при отрицательном значении ¦ ¦ ¦ выражения_2 выполняется сдвиг ¦ ¦ ¦ вправо). ¦ ¦ ¦ ¦ ¦ выражение_1 SHR выражение_2 ¦ Выражение_1 сдвигается вправо ¦ ¦ ¦ на число бит, заданных выраже- ¦ ¦ ¦ нием_2 (при отрицательном зна- ¦ ¦ ¦ чении выражения_2 выполняется ¦ ¦ ¦ сдвиг влево). ¦ L-----------------------------+----------------------------------

Операции сравнения

Операции сравнения позволяют сравнить два выражение и прове- рить их равенство или неравенство или что одно из них больше или меньше другого. Эти операции равны -1, если условие истинно (True), или 0 в противном случае. Следующая таблица показывает, как можно использовать эти операции. Операции сравнения Таблица 5.18 ------------------------------T---------------------------------¬ ¦ Выражение ¦ Значение ¦ +-----------------------------+---------------------------------+ ¦ выражение_1 EQ выражение_2 ¦ -1, если выражение_1 равно вы- ¦ ¦ ¦ ражению_2, в противном случае ¦ ¦ ¦ 0. ¦ ¦ выражение_1 NE выражение_2 ¦ -1, если выражение_ 1 не равно ¦ ¦ ¦ выражению_2, в противном случае ¦ ¦ ¦ 0. ¦ ¦ ¦ ¦ ¦ выражение_1 GT выражение_2 ¦ -1, если выражение_1 больше вы- ¦ ¦ ¦ ражения_2, в противном случае ¦ ¦ ¦ 0. ¦ ¦ ¦ ¦ ¦ выражение_1 GE выражение_2 ¦ -1, если выражение_1 больше или ¦ ¦ ¦ равно выражению_2, в противном ¦ ¦ ¦ случае 0. ¦ ¦ ¦ ¦ ¦ выражение_1 LT выражение_2 ¦ -1, если выражение_1 меньше вы- ¦ ¦ ¦ ражения_2, в противном случае ¦ ¦ ¦ 0. ¦ ¦ ¦ ¦ ¦ выражение_1 LE выражение_2 ¦ -1, если выражение_1 меньше или ¦ ¦ ¦ равно выражения_2, в противном ¦ ¦ ¦ случае 0. ¦ L-----------------------------+---------------------------------- Операции EQ или NE интерпретируют выражения, как числа без знака. Например, -1 EQ 0ffffh имеет значение -1 (если только вы не выбрали процессор 80386 или не используете режим Ideal; в пос- леднем случае значение -1 имеет выражение -1 EQ 0ffffffffh). Операции Gt, GE, LT и LE интерпретируют выражения, как числа со знаком. Например, 1 GE -1 имеет значение -1, но 1 GE 0ffffh имеет значение 0.

Задание адресного подтипа выражения

Турбо Ассемблер обеспечивает операции, которые позволяют вам изменить или переопределить тип выражений. Эти операции перечис- лены в следующей таблице: Операции переопределения типа Таблица 5.19 ----------------------------T-----------------------------------¬ ¦ Выражение ¦Значение ¦ +---------------------------+-----------------------------------+ ¦выражение_1 PTR выражение_2¦Преобразует выражение_2 к типу, оп-¦ ¦ ¦ределяемому выражением_1. При этом¦ ¦ ¦0=UNKNOWN, 1=BYTE, 2=WORD, 4=DWORD,¦ ¦ ¦6=PWORD, 8=QWORD, 10=TBYTE, 0ffffh=¦ ¦ ¦NEAR, 0fffeh=FAR, все про-¦ ¦ ¦чие=UNKNOWN (только для режима¦ ¦ ¦MASM). ¦ ¦ ¦ ¦ ¦тип PTR выражение_2 ¦Преобразует выражение к заданному¦ ¦ или тип выражение ¦адресному подтипу (только для режи-¦ ¦ ¦ма Ideal). ¦ ¦ ¦ ¦ ¦тип LOW выражение ¦Преобразует выражение к заданному¦ ¦ ¦адресному подтипу. Описанный тип¦ ¦ ¦должен быть меньше по размеру, чем¦ ¦ ¦тип выражения ( только для режима¦ ¦ ¦Ideal). ¦ ¦ ¦ ¦ ¦тип HIGH выражение ¦Преобразует выражение к заданному¦ ¦ ¦адресному подтипу. Описанный тип¦ ¦ ¦должен быть меньше по размеру, чем¦ ¦ ¦тип выражения. Возвращаемый адрес¦ ¦ ¦настраивается на старшую часть объ-¦ ¦ ¦екта, описанного адресным выражени-¦ ¦ ¦ем ( только для режима Ideal). ¦ L---------------------------+------------------------------------ Приведем некоторые примеры: IDEAL big DD 12345678h MOV ax,[WORD big] ; ax = 5678h MOV al,[BYTE PTR big] ; al = 78h MOV ax,[WORD HIGH big] ; ax = 1234h MOV ax,[WORD LOW big] ; ax = 5678h MOV al,[BYTE LOW WORD HIGH big] ; al = третьему байту big ; = 34h MASM: MOV ax,2 PTR big ; ax = 5678h MOV ax,WORD PTR big ; ax = 5678h (WORD имеет ; значение 2)

Получение типа выражения

В режиме MASM вы можете получить числовое значение типа вы- ражения путем использования операции TYPE. (В режиме MASM этого сделать нельзя, поскольку типы не описываются числовыми значения- ми.) Операция TYPE имеет следующий синтаксис: TYPE выражение Операция TYPE возвращает размер объекта, описанный адресным выражением: Значение TYPE Таблица 5.20 ---------------------------T------------------------------------¬ ¦ Выражение ¦ Значение ¦ +--------------------------+------------------------------------+ ¦ byte ¦ 1 ¦ ¦ word ¦ 2 ¦ ¦ dword ¦ 4 ¦ ¦ pword ¦ 6 ¦ ¦ qword ¦ 8 ¦ ¦ tbyte ¦ 10 ¦ ¦ short ¦ 0ffffh ¦ ¦ near ¦ 0ffffh ¦ ¦ far ¦ 0fffeh ¦ ¦ структура/объединение ¦ Размер экземпляра структуры или ¦ ¦ ¦ объединения. ¦ ¦ таблица ¦ Размер экземпляра таблицы. ¦ L--------------------------+------------------------------------- Приведем пример: avar = 5 darray dd 10 dup (1) x struc dw ? dt ? ends fp label far tavar = TYPE avar ; = 0 tbvar = TYPE davar ; = 4 tx = TYPE x ; = 12 tfp = TYPE fp ; = 0FFFFh

Переопределение сегментной части адресного выражения

Адресные выражения имеют значения, состоящие из сегмента и смещения. Вы можете задавать сегмент явно в виде сегментного ре- гистра. (Если вы задаете его, как значение группы, Турбо Ассемб- лер определяет, какой сегментный регистр нужно использовать, на основе предполагаемых значение сегментных регистров (ASSUME)). Для изменения сегментной части адресного выражения ис- пользуется следующий синтаксис: выражение_1 : выражение_2 Данная операция возвращает адресное выражение, использующее в качестве смещения выражение_2, а в качестве сегмента или значе- ния группы - выражение_1. Например: VarPtr dd dgroup:memvar ; dgrout - это группа mov cl,es[si+4] ; переопределение сегмента : ; ES

Получение сегмента и смещения адресного выражения

Для получения сегмента и смещения адресного выражения вы мо- жете использовать операции SEG и OFFSET. Операция SEG возвращает сегментную часть адресного выражения. Она имеет следующий син- таксис: SEG выражение Приведем пример исходного кода: DATASEG temp DW 0 CODESEG mov ax,SEG temp mov ds,ax ASSUME ds:SEG temp Операция OFFSET возвращает смещение адресного выражения и имеет следующий синтаксис: OFFSET выражение Заметим, что когда вы используете операцию смещения, убеди- тесь, что выражение ссылается на корректный сегмент. Например, если вы используете режим MASM и не используете упрощенные дирек- тивы, выражение: OFFSET BUFFER ; буфер - это адрес в памяти что не тоже самое, что: OFFSET DGROUP:BUFFER ; Dgroup - это группа, содержащая ; сегмент, который содержит BUFFER (если содержащий BUFFER сегмент не является первым сегментом группы). Если вы не переопределяете сегмент с помощью операции :, в режиме Ideal адреса автоматически вычисляются относительно любой группы, которой принадлежит сегмент. В режиме MASM это имеет мес- то при использовании упрощенных сегментных директив. В противном случае адреса вычисляются относительно сегмента, в котором нахо- дится объект, а не какой-либо группы.

Создание адресного выражения, использующего счетчик инструкций

Для создание адресного выражения, которое указывает на теку- щий сегмент и счетчик инструкций, можно использовать операцию THIS. В режиме Ideal можно использовать следующий синтаксис: THIS тип Синтаксис режима Ideal позволяет вам строить адресное выра- жение на основе текущего сегмента и счетчика инструкций для за- данного типа. В режиме MASM используется следующий синтаксис: THIS выражение Синтаксис режима MASM работает аналогично режиму Ideal, но для определения типа использует числовое значение выражения. Это следующие значения: 0=UNKNOWN, 1=BYTE, 2=WORD, 4=DWORD, 6=PWORD, 8=QQORD, 10=TBYTE, 0ffffh=NEAR, 0fffeh. Например: ptr1 LABEL WORD ptr2 EQU THIS WORD ; аналогично ptr1

Определение характеристик выражения

Иногда (например, в макрокоманде) бывает полезно определить характеристики заданного выражения. Для этого служат операции SYMTYPE и .TYPE. В режиме Ideal используется следующий синтаксис: SYMTYPE выражение В режиме MASM используется следующий синтаксис: .TYPE выражение Операции SYMTYPE и .TYPE возвращают описывающее выражение значение-константу. Это значение разбивается на битовые поля, по- казанные в следующей таблице: Битовые поля операций SYMTYPE и .TYPE Таблица 5.21 --------T-------------------------------------------------------¬ ¦ Бит ¦ Значение ¦ +-------+-------------------------------------------------------+ ¦ 0 ¦ Выражение является относительным указателем памяти в ¦ ¦ ¦ программе. ¦ ¦ ¦ ¦ ¦ 1 ¦ Выражение является относительным указателем на дан- ¦ ¦ ¦ ные в программе. ¦ ¦ ¦ ¦ ¦ 2 ¦ Выражение представляет собой значение-константу. ¦ ¦ ¦ ¦ ¦ 3 ¦ Выражение использует прямой режим адресации. ¦ ¦ ¦ ¦ ¦ 4 ¦ Выражение содержит регистр. ¦ ¦ ¦ ¦ ¦ 5 ¦ Идентификатор определен. ¦ ¦ ¦ ¦ ¦ 7 ¦ Выражение содержит идентификатор, определенный извне.¦ L-------+-------------------------------------------------------- Если биты 2 и 3 равны нулю, то выражение содержит косвенный регистр ([BX]). Если Турбо Ассемблер не может вычислить выражение, то опера- ция SYMTYPE возвращает соответствующие ошибки. Однако операция .TYPE в этих случаях будет возвращать значение (обычно 0).

Ссылки на структуры, объединения и смещения элементов в таблице

Элементы структур, объединений и таблиц являются глобальными переменными, значения которых представляют собой в режиме MASM смещения в структуре, объединении или таблице. Однако в режиме Ideal элементы этих типов данных рассматриваются, как локальные по отношению к типам данных. Операция точки (.) позволяет вам по- лучить смещения элементов. В режиме Ideal используется следующий синтаксис: выражение.идентификатор где "выражение" представляет адрес структуры, объединения или эк- земпляра таблицы. "Идентификатор" должен быть элементом структу- ры, объединения или таблицы. Операция точки возвращает смещение элемента в структуре. В режиме MASM также имеется версия операции точки. Однако ее функция аналогична операции + и имеет следующий синтаксис: выражение_1 + выражение_2

Описание содержимого адреса

Многие инструкции позволяют вам различать адрес и содержимое адреса. Вы можете делать это, используя квадратные скобки. Напри- мер: MOV AX,BX ; переместить BX в AX MOV AX,[BX] ; переместить в AX содержимое по ; адресу BX Приведем общий синтаксис, в котором используются квадратные скобки: [выражение] В режиме MASM квадратные скобки для выражений, являющихся адресами, не обязательны. В качестве операнда инструкции процес- соров 80х86 не может использоваться полный адрес. Вместо этого используется только сегмент (полученный с помощью операции SEG) или смещение (полученное с помощью операции OFFSET). Если ясно, что выражение является адресом, а квадратные скобки не используются, то в режиме Ideal выводится предупреждаю- щее сообщение. Это предупреждение можно запретить (см. Главу 12). Однако хорошей практикой программирования является использование скобок.

Подразумеваемое сложение

В режиме MASM сложение выражений можно выполнять несколькими способами: с помощью операции сложения (+), с помощью операции точки (.), или с помощью подразумеваемого (неявного) сложения (когда выражения разделяются квадратными и круглыми скобками). Например: MOV AX,5[BX] ; содержимое по адресу BX+5 MOV AX,5[XYZ] ; содержимое по адресу XYZ+5 Неявная операция сложения имеет следующий общий синтаксис: выражение_1 [выражение_2] или выражение_1 (выражение_2)

Получение значения старшего или младшего байта выражения

Для возврата значения старшего или младшего байта выражения можно использовать операции HIGH и LOW. Это обстоятельство может быть полезно, например, в ситуации, когда требуются только стар- шие 8 бит смещения адреса. Приведем пример операций HIGH и LOW: HIGH выражение LOW выражение Например: magic equ 1234h mov cl,HIGH magic ; cl = 12h mov cl,LOW magic ; cl = 34h

Задание 16- или 32-разрядных выражений

Если текущим выбранным процессором является процессор 80386 или старше, то Турбо Ассемблер предоставляет две операции, кото- рые определяют, будет выражение интерпретироваться как 16- или 32 -разрядное значение. Это операции SMALL и LARGE. Они имеют сле- дующий синтаксис: SMALL выражение LARGE выражение Операция SMALL помечает выражение, как представляющее 16-разрядное значение. Операция LARGE помечает его как 32-разряд- ное значение. Эти операции особенно важны в программах, при рабо- те которой в операционной среде некоторые сегменты являются 32-битовыми, а другие - 16-битовыми. Например, инструкция: JMP [DWORD PTR ABC] представляет собой косвенный переход на содержимое переменной в памяти ABC. Если у вас разрешено использование процессора 80386, то данная инструкция может интерпретироваться либо как дальний переход с использованием сегмента и 16-разрядного смещения, либо как ближний переход по 32-разрядному смещению. Для устранения неоднозначности вы можете использовать операции LARGE и SMALL: JMP SMALL [DWORD PTR ABC] Данная инструкция приводит к ассемблированию Турбо Ассембле- ром инструкции перехода таким образом, что значение, считываемое из ABC, интерпретируется как 16-разрядный сегмент и 16-разрядное смещение. При этом Турбо Ассемблер выполняет косвенный переход типа FAR (дальний переход). При использовании операций SMALL или LARGE в адресной части смещения, эти операции указывают, что адрес является 32-разряд- ным, например: JMP SMALL [LARGE DWORD PTR ABC] указывает, что переменную в памяти ABC описывает 32-разрядный ад- рес, но ее содержимое интерпретируется как 16-разрядный сегмент и 16-разрядное смещение.
                       Назад | Содержание | Вперед

 

хостинг сайтов ГиперХост — хостинг сайтов который Вы искали.

Виртуальный хостинг, Аренда VPS серверов, рация доменных имен, SSL сертификаты

Новости мира IT:

Архив новостей

Последние комментарии:

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...