- •140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.
- •Глава 1. Архитектура реального режима
- •1.1. Память и процессор
- •Глава 1
- •Глава 1
- •1.2. Распределение адресного пространства
- •Глава 1
- •1.3. Регистры процессора
- •Глава 1
- •Глава 1
- •9 7H Шестнадцатернчное обозначение числа
- •Глава 1
- •1.4. Сегментная структура программ
- •Глава 1
- •Глава 1
- •Глава 1
- •1.5. Стек
- •Глава 1
- •1.6. Система прерываний
- •Глава 1
- •Глава I
- •1.7. Система ввода-вывода
- •Глава I
- •Глава 1
- •Глава 2. Основы программирования
- •2.1. Подготовка и отладка программы
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.2. Представление данных
- •Глава 2
- •Глава 2
- •2.3. Описание данных
- •Глава 2
- •Глава 2
- •2.4. Структуры и записи
- •Глава 2
- •Глава 2
- •2.5. Способы адресации
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.7. Вызовы подпрограмм
- •Глава 2
- •2.8. Макросредства ассемблера
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 3. Команды и алгоритмы
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •3.2. Циклы и условные переходы
- •Глава 3
- •Глава 3
- •3.3. Обработка строк
- •Глава 3
- •3.4. Использование подпрограмм
- •Глава 3
- •Глава 3
- •3.5. Двоично-десятичные числа
- •Глава 3
- •Глава 3
- •3.6. Программирование аппаратных средств
- •Глава 3
- •37Ah Порт управлсш!я
- •Глава 3
- •Глава 3
- •Глава 4. Расширенные возможности
- •4.1. Архитектурные особенности
- •Глава 4
- •4.2. Дополнительные режимы адресации
- •Глава 4
- •4.3. Использование средств 32-разрядных процессоров в программировании
- •Глава 4
- •Глава 4
- •Глава 4
- •4.4. Основы защищенного режима
- •Глава 4
- •Глава 4
- •Глава 4
- •Глава 4
- •Idiv Деление целых чисел со знаком
- •Imul Умножение целых чисел со знаком
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •Into Прерывание по переполнению
- •Iret Возврат из прерывания
- •1 Lods Загрузка операнда из строки : lodsb Загрузка байта из строки lodsw Загрузка слова из строки
- •Операнд
- •Xadd память, регистр
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Содержание
Глава 2
Основы программирования
59
nmb 2 dw птЪЗ dw nmb4 dw
В чем состоит различие двух последних описаний данных' Различие есть, и весьма существенное. Хотя в обоих случаях в память записывается натуральный ряд чисел от 0 до 4, однако в первом варианте под каждое число в памяти отводится один байт, а во втором — слово. Если мы в дальнейшем будем изменять значения элементов нашего массива, то в первом варианте каждому числу можно будет задавать значения от 0 до 255, а во втором — от 0 до 65535.
Выбирая для данных способ их описания, необходимо иметь в виду, что ассемблер выполняет проверку размеров используемых данных и не пропускает команды, в которых делается попытка обратиться к байтам, как к словам, или к словам — как к байтам. Рассмотрим последний вариант описания массива numbers. Хотя под каждый элемент выделено целое слово, однако реальные числа невелики и вполне поместятся в байт. Может возникнуть искушение поработать с ними, как с байтами, перенеся предварительно в байтовые регистры:
mov AL,nmbO mov DL,nmbl mov CL,nmb2
;Переносим nmbO в AL ;Переносим nmbl в AL ;Переносим nmb2 в AL
Так делать нельзя. Транслятор сообщит о грубой ошибке — несоответствии типов, и не будет создавать объектный файл. Однако довольно часто возникает реальная потребность в операциях такого рода. Для таких случаев предусмотрен специальный атрибутивный оператор byte ptr (byte pointer, байтовый указатель), с помощью которого можно на время выполнения одной команды изменить размер операнда:
П
mov AL,byte ptr nmbO \
mov DL,byte ptr nmbl ,ч
mov CL,byte ptr nmb2
Эти команды транслятор рассматривает, как правильные.
Часто возникает необходимость выполнить обратную операцию — к паре байтов обратиться, как к слову. Для этого надо использовать оператор word ptr:
okey db 'OK'
mov AX,word ptr okey
Здесь оба байта из байтовой переменной okey переносятся в регистр АХ. При этом первый по порядку байт, т.е. байт с меньшим адресом, содержащий букву "О" (можно считать, что он является младшим в слове
"ОК"), отправится в младшую половину АХ — регистр AL, а второй по порядку байт, с буквой "К", займет регистр АН.
До сих пор речь шла о данных, которые, в сущности, являлись переменными, в том смысле, что под них выделялась память и их можно было модифицировать. Язык ассемблера позволяет также использовать константы, которые являются символическими обозначениями чисел и могут использоваться всюду в тексте программы, как наглядные эквиваленты этих чисел:
maxsize - OFFFFh mov CX,maxsize mov CX,OFFFFh
Последние две команды полностью эквивалентны.
При определении констант допустимо выполнение арифметических операций. Пусть нам надо задать позицию символа (или строки символов) на экране. Учитывая, что каждый символ записывается в видеопамяти в двух байтах (в первом — код ASCII символа, а во втором — его атрибут), строка экрана имеет длину 80 символов, а высота экрана составляет 25 строк, то для вывода некоторого символа в середину экрана его смещение в видеопамяти от начала видеостраницы можно определить следующим образом:
position=80*2*12+40*2
Такая запись достаточно наглядна, и ее легко модифицировать, если мы решим вывести символ в какую-то другую область экрана.
Константами удобно пользоваться для определения длины текстовых строк:
* mes db 'Ждите'
mes_len = S-mes
В этом примере константа mes_len получает значение длины строки mes (в данном случае 5 байт), которая вычисляется как разность значения счетчика текущего адреса после определения строки и ее начального адреса mes. Такой способ удобен тем, что при изменении содержимого строки достаточно перетранслировать программу, и та же константа mes_len автоматически получит новое значение.