Фрагмент программы


Рассмотрим следующий фрагмент программы, где в регистр AL также загружается девятый символ CharString: mov bx,OFFSET CharString+8 mov al,[bx]

Комментарии


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

Директивы определения сегментов


И в данной главе, и в предыдущей, мы уже уделили много вре-мени для пояснения того, что собой представляют директивы опреде-ления сегментов и как они влияют на составляемую вами программу. Однако, имеется еще один момент, которого мы пока не касались. Суть его в следующем: откуда Турбо Ассемблер в точности знает, в каком сегменте или сегментах находятся Читать далее

Упрощенные директивы определения сегментов


Основными упрощенными директивами определения сегментов яв-ляются директивы .STACK, .CODE, .DATA, .MODEL и DOSSEG. Рассмот-рим эти директивы, разбив их на две группы. Первой будет группа директив .STACK, .CODE и .DATA.

Директивы .STACK, .CODE и .DATA


Директивы определения сегментов .STACK, .CODE и .DATA определяют, соответственно, сегмент стека, сегмент кода и сегмент данных. Например, директива: .STACK 200h определяет стек размером в 200h (512) байт. Что касается стека, то это все, что вы сможете сделать. Необходимо просто убедиться, что в вашей программе имеется директива .STACK, и Турбо Ассемблер выделит для вас стек. Для Читать далее

Директива .MODEL


Директива .MODEL определяет модель памяти в модуле Ассембле-ра, где используются упрощенные директивы определения сегментов. Заметим, что в «ближнем» коде переходы осуществляются с помощью загрузки одного регистра IP, а в «дальнем» коде — путем загрузки регистров CS и IP. Аналогично, к «ближним» данным обращение вы-полняется только по смещению, а к «дальним» — с помощью полного адреса Читать далее

Другие упрощенные директивы определения сегментов


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

Стандартные директивы определения сегментов


Далее мы приведем такой же пример программы, как и в преды-дущем разделе, но на этот раз используем стандартные директивы определения сегментов SEGMENT, ENDS и ASSUME. DGROUP GROUP _DATA, STACK ASSUME CS:_TEXT, DS:_DATA, SS:STACK STACK SEGMENT PARA STACK ‘STACK’

Стандартные или упрощенные директивы определения сегментов


Теперь, когда вы познакомились и с упрощенными, и со стандартными директивами определения сегментов, возникает вопрос, ка-кой набор директив определения сегментов следует использовать? Ответ зависит от типа выполняемого программирования на Ассембле-ре.

Выделение данных


Теперь, когда вы знаете, как создавать сегменты, давайте рассмотрим, как можно заполнить эти сегменты осмысленными данны-ми. Сегмент стека проблемы не представляет: там находится стек, а к стеку вы можете обратиться с помощью инструкций PUSH и POP и адресоваться через регистр BP. Сегмент кода заполняется инструк-циями, которые генерируются в соответствии с мнемоникой инструк-ций вашей программы, поэтому Читать далее

Биты, байты и основания


Основной единицей памяти компьютера является бит. В бите мо-жет храниться значение 0 или 1. Бит сам по себе не особенно поле-зен. Процессор 8086 не работает непосредственно с битами, он ра-ботает с байтами, которые состоят из 8 бит. Так как бит на самом деле представляет собой цифру с основа-нием 3, байт содержит 8-разрядное число с основанием Читать далее

Представление числовых значений


Теперь, когда вы знаете о типах данных языка ассемблера, возникает вопрос, как можно представлять значения? Легче всего пользоваться десятичными значениями (то есть с основанием 10), поскольку мы привыкли к ним в повседневной жизни. Определенно, проще всего ввести: mov cx,100 ; установить счетчик в значение 100

Представление числовых значений


Теперь, когда вы знаете о типах данных языка ассемблера, возникает вопрос, как можно представлять значения? Легче всего пользоваться десятичными значениями (то есть с основанием 10), поскольку мы привыкли к ним в повседневной жизни. Определенно, проще всего ввести: mov cx,100 ; установить счетчик в значение 100

Выбор основания по умолчанию


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

Инициализированные данные


Теперь мы готовы к тому, чтобы рассмотреть способы, с по-мощью которых в Турбо Ассемблере можно определять переменные. Да-вайте сначала рассмотрим определение инициализированных данных. Директивы определения данных DS, DW, DD, DF, DP, DQ и DT позволяют вам определить переменные в памяти различного размера: DW 1 байт DW 2 байта = 1 слово DD 4 байта = Читать далее

Инициализация массивов


В одной директиве определения данных может указываться нес-колько значений. Например, директива: SampleArray DW 0, 1, 2, 3, 4 создает массив из пяти элементов с именем SampleArray, элементы которого имеют размер в слово (см. Рис. 5.7). В директивах опре-деления данных можно использовать любое число значений, умещающе-еся на строке.

Инициализация строк символов


Рассмотрим теперь создание строк символов. Символы представ-ляют собой допустимые операнды директив определения данных, поэ-тому строку символов можно определить следующим образом: String DB ‘A’, ‘B’, ‘C’, ‘D’ В Турбо Ассемблере в этом случае предусмотрена также удобная сокращенная форма: String DB ‘ABCD’

Инициализация выражений и меток


Начальное значение инициализированной переменной должно представлять собой константу, но это не обязательно должно быть число. Можно также использовать выражения: TestVar DW ((924/2)+1) а также метки:

Именованные ячейки памяти


До сих пор мы видели только, как можно присваивать имена ячейкам памяти с помощью метки, предшествующей директиве опреде-ления данных (например, DB). Другой удобный способ присваивать имя ячейке памяти предоставляет директива LABEL.

Перемещение данных


Итак, вы уже получили довольно обширное представление о при-роде языка Ассемблера, основных его концепциях и структуре прог-рамм на Ассемблере. Теперь, когда вы усвоили основы, можно сосре-доточить внимание на инструкциях языка Ассемблера, образующих ту часть программы на Ассемблере, которая и указывает процессору 8086 на необходимость выполнения конкретных действий. Давайте начнем с самой основной операции Ассемблера — Читать далее

Выбор размера данных


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

Данные со знаком и без знака


И числа со знаком, и беззнаковые числа состоят из последова-тельности двоичных цифр. Ответственность за различие этих двух видов чисел возлагается на программиста, который пишет программу на Ассемблере (то есть на вас), а не на процессор 8086. Например, значение 0FFFFh может представлять собой либо 65535, либо -1, в зависимости от того, как ваша программа его интерпретирует.

Доступ к сегментным регистрам


Хотя для перемещения значений в сегментные регистры и из них можно использовать инструкцию MOV, это особый случай, более огра-ниченный, чем другие случаи использования инструкции MOV. Если одним из операндов инструкции MOV является сегментный регистр, то другим операндом должен быть регистр общего назначения или ячейка памяти. Загрузить константу в сегментный регистр непосредственно невозможно, и невозможно непосредственно Читать далее

Перемещение данных в стек и из стека


Со стеком (областью памяти в сегменте стека, работающей по дисциплине FIFO — «первым-пришел-первым-ушел») вы уже встреча-лись. На вершину стека всегда указывает регистр SP. Для обращения к данным в стеке, с использованием режимов адресации памяти, при которых указателем базы является регистр BP, можно использовать инструкцию MOV. Например, инструкция:

Обмен данными


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

Ввод-вывод


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

Операции


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

Увеличение и уменьшение


Иногда в программе не Ассемблере требуется выполнить сложе-ние, которое состоит просто в прибавлении к операнду значения 1. Такая операция называется увеличением (инкрементацией). Аналогич-но, из содержимого регистров и переменных в памяти иногда нужно вычесть значение 1. Такая операция называется уменьшением (декре-ментацией). Для таких операций, как изменение содержимого счетчи-ка или продвижение регистров-указателей по памяти все операции сложения Читать далее

Умножение и деление


Процессор 8086 может выполнять отдельные типы операций умно-жения и деления. Эта одна из сильных сторон процессора 8086, пос-кольку во многих микропроцессорах вообще отсутствует непосредст-венная поддержка операций умножения и деления, а эти операции до-вольно сложно выполнить программным путем.

Изменение знака


Наконец, мы подошли к рассмотрению инструкции NEG, которая позволяет вам изменить (инвертировать) знак содержимого общего регистра или переменной в памяти. Например, после выполнения инс-трукций: