Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции-ASM.doc
Скачиваний:
5
Добавлен:
06.11.2018
Размер:
349.7 Кб
Скачать

Лекция 1. Основы компьютерной арифметики.

Позиционные и непозиционные системы счисления (СС). Двоичная СС. Шестнадцатеричная СС как сокращенная форма записи чисел в двоичной СС. Представление беззнаковых чисел в двоичной СС. Сложение и умножение беззнаковых чисел. Индикация переполнения в операциях с беззнаковыми числами.

Знаковые числа. Прямой код (ПК). Представление четырехразрядных двоичных чисел в ПК. Примеры сложения и вычитания чисел в ПК. Алгоритм сложения и вычитания чисел в ПК. Индикация переполнения в операциях с числами в ПК.

Дополнительный код (ДК). Представление четырехразрядных двоичных чисел в ДК. Правила перевода чисел из ПК в ДК и наоборот. Примеры сложения и вычитания чисел в ДК. Алгоритм сложения и вычитания чисел в ДК. Индикация переполнения в операциях с числами в ДК.

Системы счисления.

Система счисления – это система записи чисел.

Пусть b – натуральное число, большее единицы. Тогда любое целое неотрицательное число единственным образом представимо в виде:

a = an–1bn–1 + an–2 bn–2 + ... + a1b + a0,

где . (Это теорема, ее доказательство опустим.) Число a записывают так: a = an–1an–2...a0. Здесь b – основание системы счисления, n – разрядность числа, ai – цифры (алфавит системы счисления). Это представление называют позиционным, так как "вклад" каждой цифры определяется ее позицией в числе: последняя (младшая) цифра умножается на весовой коэффициент b0 = 1, а первая (старшая) цифра – на bn–1.

Обычно используют следующие системы счисления: = 2 – двоичная (binary), = 8 – восьмеричная (octal), = 10 – десятичная (decimal), = 16 – шестнадцатеричная (hexadecimal). Перевод чисел из одной системы счисления в другую может быть выполнен путем деления на основание системы счисления или с помощью разрядной сетки.

Пример. 2610 перевести в двоичную систему счисления. Выполняем последовательное деление 26 на 2, далее располагаем в обратном порядке последнее частное и остатки.

26

2

26

13

2

0

12

6

2

1

6

3

2

0

2

1

1

Рис. 1.1.

Получена двоичная запись исходного числа. Итак, 2610 = 110102.

Шестнадцатеричная система счисления.

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

Для = 16 представление чисел оказывается более удобным по сравнению с двоичной системой. Составим таблицу двоичных представлений для чисел от 0 до 2– 1 = 15. Арабских цифр оказывается недостаточно, поэтому цифрам выше 9 принято ставить в соответствие первые шесть букв латинского алфавита.

Числа от 0 до 15 в двоичной и 16-ричной системах счисления

b = 16

b = 2

b = 16

b = 2

b = 16

b = 2

b = 16

b = 2

0

0000

4

0100

8

1000

C (12)

1100

1

0001

5

0101

9

1001

D (13)

1101

2

0010

6

0110

A (10)

1010

E (14)

1110

3

0011

7

0111

B (11)

1011

F (15)

1111

Эту таблицу необходимо выучить наизусть.

Сформулируем правила перевода из двоичной системы в 16-ю и наоборот.

Переход 16 2. Заменить каждую цифру ее двоичным представлением. Например, 1A = 0001 1010 = 11010. (Ведущие нули можно опустить.)

Переход 2 16. Разбить число справа налево на тетрады (четверки цифр). Каждую тетраду заменить 16-ричной цифрой. Например,

10110111111100

= 10 1101 1111 1100

= 2DFC.

Наименьшая единица информации – бит (bit – сокращение от английского BInary digiT – двоичная цифра). Бит принимает два значения, которые кодируются нулем и единицей. Тем самым описываются два уровня сигнала, два состояния элемента и т.д. Если значение бита равно 1, то говорят, что он "установлен", если 0 – то "сброшен".

Ссылаться на каждый бит памяти сложно, поэтому их объединяют в группы и рассматривают это объединение как единое целое. Наименьшей группой бит, к которым можно обращаться, является байт (byte – кусок). Его составляют 8 бит. Биты нумеруют так, как показано на рисунке 1.2: справа налево, начиная с нулевого

7

6

5

4

3

2

1

0

Части байта имеют свои названия: биты с 0-го по 3-й называют младшим полубайтом, а биты с 4-го по 7-й – старшим полубайтом. Полубайт также называют тетрадой.

Используют и более крупные единицы. Слово (word) составляют два байта:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

старший байт

младший байт

Двойное слово (doubleword) составляют два слова, или четыре байта.

31

30

29

16

15

2

1

0

старшее слово

младшее слово

Для байта, слова, двойного слова используется обобщенный термин "ячейка".

Странная на первый взгляд нумерация битов (слева направо, начиная с нуля) имеет объяснение. Если в ячейке записано двоичное число, то номер бита k является показателем в весовом коэффициенте bk позиционного представления числа. Пусть, например, в байте установлены 5-й и 2-й бит, а остальные сброшены. Это означает, что в нем записано число 1*25 + 1*22 = 32 + 4 = 36.

0-й бит ячейки называют также младшим битом. "Самый левый" бит носит название старший бит. Нельзя его называть первым: первым является бит "второй справа".

Для записи содержимого байта требуется две 16-ричные цифры, содержимого слова – четыре цифры, содержимого двойного слова – восемь цифр. При этом по 16-ричному представлению слова легко выделить содержимое старшего и младшего байта. Например, в слове записано C7FB. Тогда в старшем байте записано C7, а в младшем FB.

Сложение и вычитание беззнаковых чисел.

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

Прямой код.

Прямой код (ПК) используется для представления знаковых чисел. При этом старший разряд числя является знаковым (0 – «+», 1– «-»), а оставшиеся разряды – значащими (модулем числа). Например: +142 = 0.1110, –142 = 1.1110.

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

Рассмотрим выполнение операции сложения чисел в ПК. Алгоритм сложения имеет следующий вид.

В начале проверяется равенство знаков слагаемых. При их равенстве выполняется сложение модулей чисел, и результату присваивается знак одного из операндов. Если при сложении модулей возникает перенос из старшего разряда, то имеет место переполнение, и результат является ошибочным.

Если знаки слагаемых не равны, для определения результата необходимо из большего модуля числа вычесть меньший модуль числа, и результату присвоить знак большего по модулю числа. Отметим, что при сложении чисел с разными знаками переполнение невозможно.

Таким образом, при сложении чисел в ПК признаком переполнения является наличие переноса из старшего разряда при сложении модулей чисел.

Дополнительный код.

Формируется из числа в прямом коде и позволяет выполнять сложение чисел по более простой схеме по сравнению с прямым кодом.

Перевод чисел из ПК в ДК выполняется по следующим правилам:

Положительное число в ДК такое же, как и в ПК.

Если число отрицательное, то для перевода его в ДК нужно знак сохранить, а модуль числа инвертировать и прибавить единицу.

Например.

0.1010ПК = 0.1010ДК = 1010.

1.1011ПК = 1.0101ДК = –1110.

Отметим, что в ПК число 1.0000 означает то же, что и 0.0000. В дополнительном коде число 1.0000 означает число –1610 и является корректным с точки зрения ДК.

Рассмотрим выполнение операции сложения чисел в ДК.

Считая, что оба операнда уже заданы в ДК, выполняется их суммирование, после чего сравниваются переносы из знакового (старшего) и в знаковый разряд. Переполнение результата имеет место при неравенстве переносов. В случае переполнения результат считается неверным.

Преимущества алгоритма сложения чисел в ДК по сравнению с ДК заключаются в следующем.

  1. Знаки операндов участвуют в операции сложения наравне со значащими разрядами. Это приводит к тому, что знак результата формируется автоматически, без дополнительных проверок.

  2. Алгоритм сложения в ПК использует операцию двоичного вычитания, которая крайне сложно реализуется с помощью электронной аппаратуры в связи с использованием заемов. В тоже время операция двоичного сложения реализуется сравнительно просто.

  3. Доступный диапазон чисел в ДК на одно число больше, чем в ПК (при одинаковой разрядности операндов).

Вычитание чисел со знаком.

Вычитание сводится к сложению, при этом вычитаемое предварительно умножается на минус единицу: A – B = A + (-B).

Для того, что число в ПК умножить на (-1), достаточно инвертировать знак числа.

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

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

Лекция 2. Функциональная организация ЭВМ на базе процессора i8086.

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

Центральным узлом современных ЭВМ является однокристальный микропроцессор. Процессор серии Intel 8086, выпущенный в 1979 году, является основанием большой ветви процессоров семейства x86 (80286, 80386, 80486, Pentium и т.д.) По современным стандартам процессор 8086 обладает скромными возможностями. Но тем не менее, он продолжает играть важную роль, являясь составной частью современных микропроцессоров и обеспечивая их программную совместимость.

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

Память.

Процессор 8086 может работать с внешней памятью объемом до 1 мегабайт (220=1048576 ячеек памяти, каждая размером 8 бит). Первый байт памяти имеет номер (физический адрес) 0, последний – 0FFFFFh). Адрес 0FFFFFh – это шестнадцатеричная форма записи, о чем говорит суффикс h. В десятичном виде это эквивалентно значению 1048575.

Шестнадцатеричный ---------------------- Десятичный адрес

адрес 00000 | | 0

00001 | | 1

00002 | | 2

00003 | | 3

00004 | | 4

00005 | | 5

00006 | | 6

00007 | | 7

00008 | | 8

00009 | | 9

0000A | | 10

0000B | | 11

0000C | | 12

0000D | | 13

0000E | | 14

0000F | | 15

00010 | | 16

|--------------------|

. .

. .

. .

FFFEF | | 1048559

FFFF0 | | 1048560

FFFF1 | | 1048561

FFFF2 | | 1048562

FFFF3 | | 1048563

FFFF4 | | 1048564

FFFF5 | | 1048565

FFFF6 | | 1048566

FFFF7 | | 1048567

FFFF8 | | 1048567

FFFF9 | | 1048569

FFFFA | | 1048570

FFFFB | | 1048571

FFFFC | | 1048572

FFFFD | | 1048573

FFFFE | | 1048574

FFFFF | | 1048575

----------------------

Один байт размером 8 бит может содержать один символ, или одно целое значение в диапазоне от 0 до 255. Два байта (машинное слово) могут одно целое значение в диапазоне от 0 до 65535. Процессор 8086 может работать как с байтами, так и со словами. Машинное слово – максимальная по размеру единица информации, обрабатываемая процессором непосредственно, т.е. на уровне аппаратуры (2 байта для процессора 8086). Четыре вместе взятых байта (двойное слово) могут содержать целое значение в диапазоне от 0 до 4294967295. Процессор 8086 не обрабатывает двойные слова непосредственно, однако при наличии соответствующего программного обеспечения он может выполнять виртуальную обработку любых типов данных, хотя и медленнее.

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

Ввод-вывод.

Процессор 8086 обеспечивает работу с внешними устройствами с помощью портов, которые представляют собой специальные адреса ввода-вывода в отдельном от 1 мегабайта адресном пространстве размером 64 К.

Адрес ввода-вывода (порт)

----------------------

0000 | |

0001 | |

0002 | |

0003 | |

0004 | |

0005 | |

0006 | |

0007 | |

0008 | |

0009 | |

000A | |

|--------------------|

. .

. .

. .

|--------------------|

FFF5 | |

FFF6 | |

FFF7 | |

FFF8 | |

FFF9 | |

FFFA | |

FFFB | |

FFFC | |

FFFD | |

FFFE | |

FFFF | |

----------------------

Адресов ввода-вывода у процессора 8086 намного меньше, чем адресов памяти. В то время как технически возможно реализовать 64К адресов ввода-вывода, практически имеются только 4К адресов. Адреса ввода-вывода не используются для хранения значений, а служат для передачи данных в каналы устройств ввода-вывода.

Некоторые устройства ввода-вывода представляют собой устройства с отображаемой памятью. Это означает, что они управляются через обычные адреса памяти, а не через адреса ввода-вывода. Особенно это относится к дисплейным адаптерам, которые могут использовать 16К, 32К или даже 256К пространства адресов памяти процессора 8086 для своих битовых массивов (массивов, описывающих точки, которые адаптеры выводят на экран). Данные устройства могут управляться как с помощью адресов ввода-вывода, так и с помощью адресов отображаемой памяти. Фактически, при работе с дисплейными адаптерами для некоторых функций используются инструкции ввода-вывода, а для других – адреса памяти.

Процессор.

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

Регистры делятся на четыре категории: сегментные регистры, регистры общего назначения, регистр флагов и указатель инструкций. В процессоре 8086 регистры имеют размер слова (16 бит) или байта (8 бит).

В целом структурная схема вычислительной машины выглядит следующим образом.

Центральный процессор (ЦП) соединен с остальными устройствами через так называемый шинный интерфейс, представленный тремя шинами: шиной адреса (ША), шиной данных (ШД) и шиной управления (ШУ). ША имеет 20 разрядов, что позволяет адресовать 220 = 1 Мб ячеек оперативной памяти (ОП). 16-разрядная ШД за один такт работы может передавать, как два, так и один байт данных, в зависимости от исполняемой процессорной команды. 16-разрядная ШУ является программно недоступной, и ее содержимое формируется процессором автоматически. Сигналами ШУ являются например, сигналы разрешения записи/чтения ОП или периферийных устройств (ПУ).

ПУ подключены к шинам через порты ввода-вывода. Функцией последних является передача/прием информации от одного физического устройства к другому. При этом для идентификации номера порта используются младшие 16 разрядов шины адреса, что ограничивает количество портов числом 216=65536. Обмен данными с портами происходит посредством восьми младших разрядов ШД, т.е. в побайтовом режиме.

Лекция 3. Сегментация памяти.

Как было сказано ранее, максимально возможный объем оперативной памяти, доступный процессору, определяется разрядностью шины адреса и составляет 220 байт = 1 Мб. Однако процессор 8086 является 16-разрядным, и в его внутренней памяти (регистрах) могут быть размещены только 16-разрядные значения. Таким образом, хранить в регистре процессора полный 20-разрядный физический адрес памяти оказывается невозможным. Для обхода этого ограничения в процессоре 8086 используется принцип сегментации памяти.

С помощью 16 двоичных разрядов, помещающихся в регистры процессора, можно адресовать лишь 216 = 26 210 = 26 К = 64 К ячеек памяти. Разделим мысленно все пространство оперативной памяти на блоки по 16 байт и каждый такой блок назовем параграфом. Можно подсчитать, что 1 мегабайт памяти содержит 220/16 = 65536 параграфов. Если рассматривать адрес ячейки памяти в 16-ричном виде (например, адрес D4A9Ch), то можно говорить, что эта ячейка располагается в параграфе с порядковым номером D4A9h (старшие 4 16-ричных разряда адреса) и является 12-й (0Ch) ячейкой в параграфе. Ячейки, являющиеся первыми в каждом параграфе, имеют ноль в младшем 16-ричном разряде адреса. Например, начальными в своих параграфах являются ячейки с адресами 00000h, 00010h , 9D230h, FFFF0h.

Помимо параграфов, в оперативной памяти можно выделить блоки размером 64К, называемые сегментами. Отличительной особенностью сегментов от произвольных блоков памяти является то, что любой сегмент всегда начинается на границе параграфа, т.е. на ячейке, 16-ричный адрес которой всегда заканчивается нулем. Таким образом, для указания начального адреса сегмента не обязательно указывать полный адрес ячейки памяти, а достаточно указать номер параграфа, с которого начинается сегмент (старшие 16 двоичных разрядов полного 20-разрядного адреса). Чтобы из адреса сегмента получить полный адрес ячейки памяти, достаточно приписать к нему четыре младших двоичных разряда, равных нулю (или, иным словами, умножить на 16). Важным моментом является то, что начальный адрес сегмента можно хранить в 16-разрядных регистрах процессора.

Используя подобную сокращенную запись адреса, можно указать на любую ячейку, являющуюся первой в параграфе. Тем не менее, остальные 15 ячеек каждого параграфа окажутся недоступными, поскольку младшая часть их адреса отлична от нуля. Для обеспечения доступа к произвольной ячейке памяти наряду с адресом сегмента используется смещение, представляющее собой 16-разрядную величину. При этом полный физический адрес ячейки памяти получается следующим образом:

(физический адрес) = (адрес сегмента)*10h + (смещение)

Например, если адрес сегмента равен 2A45h, адрес смещения – 09C3h, то полный адрес ячейки памяти равен 2A45h*10h+09C2h = 2A450h+09C2h = 2AE12h. Часто полный адрес записывают в виде адреса сегмента и смещения, разделенных двоеточием: 2A45:09C2.

Если преобразование сегмента и смещения в физический адрес выполняется однозначно, то представление физического адреса в виде сегмента и смещения может быть выполнено несколькими равноправными способами. Пусть физический адрес ячейки памяти равен 00095h. Рассматривая сегмент с адресом 0000h, можно вычислить, что смещение до данной ячейки составляет 0095h. В этом случае машинное представление адреса ячейки имеет вид 0000:0095.

В то же время указанная ячейка принадлежит сегменту, начинающемуся с адреса 0001h, т.е. с параграфа с номером 0001. В этом случае смещение до адреса 00095h составит 00095h-00010h=00085h. При этом машинный адрес ячейки будет иметь вид 0001:0085.

В общем случае каждая ячейка памяти может принадлежать одному из 65536/16=4096 возможных сегментов, и ее адрес может быть записан 4096 способами. Несмотря на это, часто используют так называемую нормализованную запись машинного адреса, при которой смещение может находиться в пределах от 0 до 15, а сегмент начинается с параграфа, в котором находится ячейка. Для рассмотренного выше примера нормализованный машинный адрес будет иметь вид: 0009:0005. Получение нормализованного адреса оказывается наиболее простым: в качестве адреса сегмента берутся первые 4 16-ричных цифры физического адреса, а для адреса смещения – последняя 16-ричная цифра.

Сегментные регистры.

Во время выполнения программы можно использовать одновременно 4 сегмента памяти:

  • сегмент кода: в нем содержится машинный код выполняемой программы.

  • сегмент данных: содержит переменные программы.

  • сегмент стека: используется при обращении к подпрограммам.

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

Для хранения адресов данных сегментов в процессоре 8086 используются четыре сегментных регистра: CS (Code Segment), DS (Data Segment), SS (Stack Segment) и ES (Extended Segment). Каждый регистр является 16-разрядным и используется процессором автоматически.

При загрузке программы DOS анализирует таблицу занятости оперативной памяти, отыскивает в ней любой достаточный по размеру участок и загружает в него программу. Если такого участка нет, DOS может перегруппировать в памяти ранее загруженные программы и освободить требуемый участок.

После расположения в памяти программы DOS записывает адреса сегментов программы в соответствующие сегментные регистры процессора и передает управление первой команде в сегменте кода.

Следует отметить, что DOS выделяет для каждого сегмента столько памяти, сколько определено текстом программы (не обязательно полные 64Кб). Например, если общий объем памяти для хранения переменных не превышает 5 параграфов, то под сегмент данных будет выделено 5 параграфов, а с шестого может начинаться другой сегмент.

Поскольку в оперативной памяти, помимо пользовательской программы, находятся операционная система, драйверы устройств и резидентные программы, сегменты для пользовательской программы выделяются в свободных областях памяти. По этой причине на разных компьютерах с разным набором драйверов (и даже на одном компьютере) при разных запусках программы могут быть выделены разные области памяти, и содержимое сегментных регистров может быть различным. Тем не менее, это никак не сказывается на работе программы. Данный принцип (принцип возможности использования любого свободного участка памяти для работы программы) называется принципом перемещаемости программ. На этапах редактирования и трансляции формируются относительные адреса всех объектов программы. Это означает, что адреса любой команды или любого поля данных относительно начала соответствующего сегмента остаются неизменными в процессе выполнения программы и не зависят от адресов сегментов программы.

Лекция 4. Язык Ассемблера процессора 8086.

Язык ассемблера представляет собой машинный язык в символической форме, которая более понятна и удобна человеку.

Язык ассемблера микропроцессора Intel 8086 является довольно сложным, что в первую очередь объясняется сегментной организацией памяти и одновременной адресацией четырех сегментов. В языке имеется более 100 базовых символических команд, в соответствии с которыми ассемблер генерирует более 3800 машинных команд. Кроме того, в распоряжении программиста имеется более 20 директив, предназначенных для распределения памяти, инициализации переменных, условного ассемблирования и т.д.

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

Командные операторы в Ассемблере записываются в следующем формате:

{Метка:} {Префикс} Мнемоника {Операнд1}{,Операнд2} {;Комментарий}

где фигурные скобки обозначают необязательные поля.

Рассмотрим назначение отдельных полей данного формата:

1) Метка представляет собой определяемое пользователем имя, заканчивающееся двоеточием. Значением метки является текущее значение счетчика ячеек (адресов) в текущем сегменте кода, т.е. адрес отмеченной команды. Метки как операнды используются только в командах передачи управления, и при этом двоеточие в конце

ссылки на метку не ставится.

2) Префикс заставляет ассемблер сформировать один из префиксных байт – блокировки LOCK или повторения REP, который непосредственно предшествует команде.

3) Мнемоника кода операции представляет собой заранее определенное и неизменяемое имя, которое идентифицирует тип генерируемой машинной команды.

4) Операнды задают адреса данных или сами данные, необходимые в данной команде.

5) Комментарий предназначен только для документирования программы. Он всегда начинается с точки с запятой.

Регистры общего назначения.

К регистрам общего назначения (РОНам) относятся, в частности, т.н. HL-регистры. Это четыре 16-разрядных регистра с именами AX, BX, CX, DX. Можно также обращаться по отдельности к старшим и младшим байтам этих регистров. Например, старший байт AX – это регистр AH (High – старший), младший байт – AL (Low – младший). (Именно поэтому эта подгруппа регистров носит название HL – high-low)

15

8

7

0

AX

AH

AL

BX

BH

BL

CX

CH

CL

DX

DH

DL

Когда-то в микропроцессоре 8080 имелись 8-разрядные регистры A, B, C, D. В 8086 регистры стали 16-разрядными (eXtended – расширенными). Поэтому их названия приобрели суффикс X. Названия регистров можно расшифровать так:

AX – accumulator – аккумулятор,

BX – base register – регистр базы,

CX – counter register – счетчик,

DX – data register – регистр данных.

Эти регистры могут единообразно участвовать в различных операциях. Но в ряде команд использование регистров специализировано. Например, для организации циклов используется регистр CX, что оправдывает его название – "счетчик".

Любые преобразования данных в процессоре производятся с участием тех или иных регистров общего назначения.

Переменные.

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

Переменная – это единица программных данных, имеющая символическое имя.

Большинство ассемблерных программ начинается с определения данных, которыми они будут оперировать. Распределение ячеек памяти и присвоение им идентификаторов осуществляется в сегменте данных программы с помощью директив DB (Define Byte - определить байт), DW (Define Word - определить слово), DD (Define Doubleword - определить двойное слово), DQ (Define Quadword - определить 4 слова) или DT (Define Tenbyte - определить 10 байтов).

Операторы распределения данных имеют следующий формат:

Имя DB нач.значение, {нач.значение}, ...

Имя DW нач.значение, {нач.значение}, ...

Имя DD нач.значение, {нач.значение}, ...

Имя DQ нач.значение, {нач.значение}, ...

Имя DT нач.значение, {нач.значение}, ...

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

Для задания начальных значений могут использоваться числовые константы и символьные цепочки. Если не нужно задавать начальное значение переменной, то вместо константы ставится вопросительный знак.

Например, оператор

alpha DW 0Ah

резервирует слово памяти, присваивает ему идентификатор alpha и заносит в него код 000A;

string DB 'Привет'

резервирует 6 байт памяти, заносит в них строку символов и присваивает этой строке идентификатор string.

Чтобы точно определить тип переменной, на которую производится ссылка, ассемблер использует операторы BYTE PTR, WORD PTR и DWORD PTR (указатель на байт, слово и двойное слово соответственно).

Для инициализации массивов применяется конструкция DUP, которая в общем случае имеет вид:

n DUP (нач. значение, {нач. значение}, ...)

где параметр n задает число повторений элементов, находящихся в круглых скобках.

Например, оператор

Addr DD 20 DUP (?)

резервирует место для 20 полных адресов и присваивает этому массиву идентификатор Addr.

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

Константа – это численное значение, вычисляемое во время ассемблирования по заданному выражению.

Численные константы допускается представлять в системах счисления с основаниями 2, 8, 10 и 16. За младшей цифрой должен находиться однобуквенный дескриптор системы счисления: B – двоичная, O или Q – восьмеричная, D (необязательно) – десятичная, H – шестнадцатеричная. Шестнадцатеричная константа должна быть дополнена слева незначащим нулем. Например: 124, 124D, 124O, 124H, 101B, 0ABH.

Символьные константы.

Символьная константа – это любой символ в коде ASCII. Символьная строка может содержать до 255 символов и должна быть заключена в одиночные кавычки. Например: ‘12345’, ‘Error!’, ‘Yes/No’.

Лекция 5. Система команд процессора 8086.

Систему команд процессора 8086 образуют 113 базовых команд, многие из которых допускают использование разнообразных режимов адресации.

По функциональному назначению выделяют следующие группы команд:

– команды передачи данных;

– команды арифметических операций;

– команды логических операций и сдвигов;

– команды передачи управления;

– цепочечные команды;

– команды управления микропроцессором.

При описании команд условимся использоваться следующие обозначения:

dst – получатель,

src – источник,

mem – адрес памяти (смещение), заданный любым методом адресации,

reg – регистр общего назначения,

sreg – сегментный регистр,

aс – регистр-аккумулятор (AL или AX),

data – непосредственные данные.

Общие команды передачи данных.

В эту подгруппу входят команды, осуществляющие передачу регистр-регистр, регистр-память и память-регистр. Наиболее мощной среди них является команда MOV.

Команда MOV.

Эта команда имеет следующее обобщенное представление:

MOV dst, src

т.е. первым указывается операнд-получатель, а вторым - операнд-источник. Одним из операндов, как правило, является регистр.

Команда осуществляет передачу:

регистр > регистр,

регистр > память,

память > регистр,

непосредственные данные > регистр,

непосредственные данные > память,

регистр > сегментный регистр,

память > сегментный регистр,

сегментный регистр > регистр,

сегментный регистр > память.

Допустимые форматы команды:

MOV mem/reg1, mem/reg2

MOV mem/reg, data

MOV sreg, mem/reg

MOV mem/reg, sreg

Например:

MOV AX, 0B45H ; AX:=B4516

MOV AL, 0 ; AL:=0

MOV AL, ‘0’ ; AL:=48

MOV BX, AX ; BX:=AX

MOV CX, counter ; CX:=counter

MOV counter, DX ; counter := DX

MOV counter, max_counter ; Недопустимо: два адреса памяти в команде!

Помимо команды MOV, к командам передачи данных относятся: XCHG, XLAT, LEA, LDS, LES, LAHF, SAHF. Они используются значительно реже, чем MOV, и их описание можно найти в справочниках по языку Ассемблер.

Команды арифметических операций.

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

Арифметические операции выполняются над целыми числами четырех типов: беззнаковыми двоичными, знаковыми двоичными, упакованными десятичными и неупакованными десятичными. Длина чисел может быть 8 или 16 бит.

Диапазоны чисел:

беззнаковое 8-битное: 0 - 255,

беззнаковое 16-битное: 0 - 65535,

знаковое 8-битное: -128 - +127,

знаковое 16-битное: -32768 - +32767.

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

Команды сложения.

Команда ADD.

Команда ADD позволяет производить сложение 8- или 16-битовых двоичных чисел в режиме регистр-регистр, регистр-память и память-регистр, причем адресация памяти осуществляется в любом допустимом режиме. Общее представление команды имеет вид

ADD dst, src

т.е. первый операнд складывается со вторым и результат операции замещает первый операнд.

Формат команды:

ADD mem/reg1,mem/reg2

ADD mem/reg, data

Например:

ADD CX, 10 ; CX := CX + 10

ADD DX, BX ; DX := DX + BX

ADD BX, step ; BX := BX + step

ADD step, AL ; step := step + AL

Помимо команды ADD, к командам сложения относятся ADC и INC (см. справочники).

Команды вычитания.

Команда SUB.

Команда SUB позволяет производить вычитание 8- или 16-битных двоичных чисел. Общее представление команды имеет вид

SUB dst, src

т.е. второй операнд вычитается из первого и результат операции замещает первый операнд.

Формат команды:

SUB mem/reg1,mem/reg2

SUB mem/reg,data

Например:

SUB AX, BX ; AX := AX – BX

SUB CX, step ; CX := CX – step

SUB step, DX ; step := step – DX

Помимо SUB, к командам вычитания относятся SBC и DEC (см. справочники).

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

Формат команды:

NEG mem/reg

Например:

NEG BX ; BX := –BX

Команды умножения.

Микропроцессор 8086 имеет две команды умножения: для беззнаковых и для знаковых двоичных чисел. Умножение десятичных чисел требует использования специальных команд коррекции, которые будут рассматриваться позднее.

Команда MUL

Команда умножения беззнаковых целых чисел MUL выполняет умножение адресуемого операнда на содержимое аккумулятора. Общее представление команды имеет вид

MUL src

При операции над байтами одним из множителей всегда является регистр AL, а 16-битный результат операции всегда помещается в регистр AX. При операции над словами одним из множителей всегда является регистр AX, а произведение длиной 32 бита формируется в регистрах DX (старшее слово) и AX (младшее слово).

Формат команды:

MUL reg

MUL mem

Команда IMUL

Команда IMUL аналогична команде MUL, но сомножители и произведение интерпретируются как знаковые двоичные числа в дополнительном коде.

Формат команды:

IMUL reg

IMUL mem

Команды деления.

Микропроцессор 8086 имеет две команды целочисленного деления: для беззнаковых и для знаковых двоичных чисел.

Команда DIV

Команда деления беззнаковых чисел DIV производит деление содержимого аккумулятора и его расширения на содержимое адресуемого операнда.

При делении 16-битного делимого на 8-битный делитель делимое помещают всегда в регистр AX. В результате выполнения операции частное формируется в регистре AL, а остаток – в AH.

Заметим, что частное представляет собой 8-битовое значение. Это означает, что результат деления 16-битового операнда на 8-битовый операнд должен превышать 255. Если частное слишком велико, то генерируется прерывание 0 (прерывания по делению на 0). Инструкции:

mov ax,0fffh

mov bl,1

div bl

генерируют прерывание по делению на 0 (как можно ожидать, прерывание по делению на 0 генерируется также, если 0 используется в качестве делителя).

При делении 32-битного делимого на 16-битный делитель старшая часть делимого помещается в регистр DX, а младшая – в AX. В результате выполнения операции частное формируется в регистре AX, а остаток – в DX.

Формат команды:

DIV reg

DIV mem

Команда IDIV

Команда IDIV аналогична команде DIV, но делимое, делитель и частное интерпретируются как знаковые двоичные числа в дополнительном коде.

Формат команды:

IDIV reg

IDIV mem

В ряде случаев перед выполнением деления знаковых чисел требуется выполнение специальной команды преобразования (расширения) знакового операнда.

Команды преобразования

Команда преобразования байта в слово CBW расширяет знак содержимого регистра AL в регистр AH. Команда преобразования слова в двойное слово CWD передает знак содержимого регистра AX во все биты регистра DX.

Форматы команд:

CBW

CWD

Команды логических операций

Логические операции представлены командами NOT (инверсия), AND (конъюнкция), OR (дизъюнкция), XOR (исключающее ИЛИ) и командой TEST, которая выполняет конъюнкцию операндов, но не изменяет их значений. Все логические операции являются поразрядными, т.е. выполняются независимо для всех бит операндов.

Форматы команд:

AND mem/reg1,mem/reg2

AND mem/reg,data

OR mem/reg1,mem/reg2

OR mem/reg,data

XOR mem/reg1,mem/reg2

XOR mem/reg,data

TEST mem/reg1,mem/reg2

TEST mem/reg,data

NOT mem/reg

Команды сдвигов

Команды сдвигов подразделяются на команды простых сдвигов и команды циклических сдвигов. Циклические сдвиги влияют только на флаги OF и CF, а обычные изменяют пять флажков: OF, SF, ZF, PF и CF. Команды сдвигов могут работать как с байтами, так и со словами.

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

Команды RCL и RCR называются командами циклического сдвига влево и вправо через перенос, так как флажок CF расширяет сдвигаемый операнд на один бит. Таким образом, значение из CF загружается в освобождающийся бит, а выдвигаемый бит помещается в CF.

Команды SHL и SHR реализуют логический сдвиг влево и вправо соответственно. Для логического сдвига характерно, что в освобождающийся бит загружается нуль, а выдвигаемый бит теряется.

Команды SAL и SAR предназначены для арифметического сдвига влево и вправо. Арифметический сдвиг вправо отличается от логического сдвига тем, что знаковый бит не сдвигается, а дублируется в соседнем правом бите, сохраняя тем самым знак числа. Арифметический сдвиг влево эквивалентен логическому, поэтому мнемоники SAL и SHL обозначают одну и ту же машинную команду. Команды арифметического сдвига по существу реализуют умножение и деление чисел без знака на степень числа 2.

Поле операнда команд сдвига имеет вид mem/reg,count. Операнд count определяет число сдвигов и может быть указан как константа 1 или как регистр CL. В первом случае выполняется сдвиг на один бит, а во втором число сдвигов определяется содержимым регистра CL, которое воспринимается как беззнаковое число.

Формат команды:

ROL mem/reg,1 ROL mem/reg,CL

ROR mem/reg,1 ROR mem/reg,CL

RCL mem/reg,1 RCL mem/reg,CL

RCR mem/reg,1 RCR mem/reg,CL

SHL mem/reg,1 SHL mem/reg,CL

SHR mem/reg,1 SHR mem/reg,CL

SAL mem/reg,1 SAL mem/reg,CL

SAR mem/reg,1 SAR mem/reg,CL

Регистр флагов (Flags)

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

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

OF

DF

IF

TF

SF

ZF

AF

PF

CF

Флагами здесь называются отдельные биты. Каждый из них характеризует некоторое состояние или режим. Если бит содержит единицу ("установлен") – значит, состояние или режим, за которые отвечает этот бит имеют место (ДА). Если бит содержит нуль ("сброшен") – НЕТ.

Флаги делятся на три группы: флаги состояния – CF, PF, AF, ZF, SF, OF – отображают некоторые характеристики результата выполнения команды (они устанавливаются или сбрасываются центральным процессором); системные флаги – TF, IF и флаг управления DF – задают режимы работы ЦП и явно устанавливаются специальными командами. Опишем назначение флагов состояния.

CF – carry flag – флаг переноса. При сложении сюда попадает бит переноса из знакового разряда. CF изменяется и по результатам некоторых других команд.

PF – parity flag – флаг четности. Установлен, если младший байт результата содержит четное число единиц. Используется для тестирования памяти.

AF – auxiliary flag – флаг вспомогательного переноса. Равен значению бита переноса из младшей тетрады в старшую в младшем байте (т.е. перенос из 3-го в 4-й бит). Используется при работе с двоично-десятичными числами. ZF – zero flag – флаг нуля. Установлен, если результат нулевой; сброшен, если результат ненулевой.

SF – sign flag – флаг знака. Равен знаковому биту результата. Стало быть, установлен если результат отрицательный; сброшен, если неотрицательный.

OF – overflow flag – флаг знакового переполнения. Установлен, если результат арифметической операции над знаковыми операндами лежит вне допустимого диапазона.

Команды передачи управления.

Сегментная организация программной памяти определяет две основные разновидности команд передачи управления. Передача управления в пределах текущего сегмента кода называется внутрисегментной – при этом модифицируется только регистр IP и адрес перехода может быть представлен одним словом. Такая передача управления называется ближней (тип NEAR), а ее вариант с сокращенным диапазоном адресов переходов – короткой. Передача управления за пределы текущего сегмента кода называется межсегментной или дальней (тип FAR) - при этом необходимо модифицировать содержимое регистров IP и CS и адрес перехода представляется двумя словами (сегмент:смещение).

Команды передачи управления процессора 8086 подразделяются на команды безусловных переходов, условных переходов, вызовов, возвратов, управления циклами и команды прерываний.

Команды передачи управления анализируют, но не изменяет состояние регистра флагов (за исключением команды IRET).

Команды безусловных переходов.

Команды безусловного перехода имеют общую мнемонику JMP. Команда короткого безусловного перехода содержит во втором байте смещение, которое интерпретируется как знаковое целое. Диапазон значений байта смещения составляет -128 ... +127. Если смещение положительное, осуществляется переход вперед, а если отрицательное – переход назад.

Команда ближнего безусловного перехода может либо непосредственно содержать 16-битное смещение, либо косвенный адрес 16-битного смещения. Диапазон смещения составляет -32768 ... +32767 байт относительно адреса команды, находящейся после команды JMP.

Команда дальнего безусловного перехода реализует прямой и косвенный межсегментнные переходы.

Форматы команд:

JMP dispL – короткий переход

JMP disp – ближний прямой переход

JMP mem/reg – ближний косвенный переход

JMP addr – дальний прямой переход

JMP mem – дальний косвенный переход

Команды условного перехода.

В системе команд процессора 8086 имеется 19 двухбайтных команд условных переходов. При выполнении этих команд анализируется некоторое условие, закодированное текущими состояниями флагов, и если оно выполняется, то осуществляется переход, а если нет, то выполняется следующая по порядку команда.

Все условные переходы являются короткими. Некоторые команды для удобства программирования могут иметь несколько различных мнемонических обозначения.

Мнемонические обозначения команд:

1) Команды для работы с беззнаковыми числами. Переход на метку осуществляется, если:

+-----------------------------------------------------------------------+

¦ мнемоника команд ¦состояние флажков¦ соотношение двух чисел ¦

¦ условного перехода +-----------------¦ ¦

¦ ¦ CF ¦ ZF ¦ ¦

+---------------------+--------+--------+-------------------------------¦

¦ JB / JNAE / ¦ 1 ¦ - ¦ ниже / не выше или равны / ¦

¦ JC ¦ ¦ ¦ есть перенос ¦

+---------------------+--------+--------+-------------------------------¦

¦ JBE / JNA ¦ 1 ¦ 0 ¦ ниже или равны / не выше ¦

¦ ¦ 0 ¦ 1 ¦ ¦

¦ ¦ 1 ¦ 1 ¦ ¦

+---------------------+--------+--------+-------------------------------¦

¦ JNB / JAE / ¦ 0 ¦ - ¦ выше или равны / не ниже / ¦

¦ JNC ¦ ¦ ¦ нет переноса ¦

+---------------------+--------+--------+-------------------------------¦

¦ JNBE / JA ¦ 0 ¦ 0 ¦ выше / не ниже или равны ¦

+-----------------------------------------------------------------------+

2) Команды для работы со знаковыми числами.

+-----------------------------------------------------------------------+

¦ мнемоника команд ¦состояние флажков¦ соотношение двух чисел ¦

¦ условного перехода +-----------------¦ ¦

¦ ¦ OF ¦ ZF ¦ SF ¦ ¦

+---------------------+-----+-----+-----+-------------------------------¦

¦ JL / JNGE ¦ 0 ¦ - ¦ 1 ¦ меньше / не больше или равны ¦

¦ ¦ 1 ¦ - ¦ 0 ¦ ¦

+---------------------+-----+-----+-----+-------------------------------¦

¦ JNL / JGE ¦ 0 ¦ - ¦ 0 ¦ больше или равны / не меньше ¦

¦ ¦ 1 ¦ - ¦ 1 ¦ ¦

+---------------------+-----+-----+-----+-------------------------------¦

¦ JLE / JNG ¦ 0 ¦ 1 ¦ 1 ¦ меньше или равны / не больше ¦

¦ ¦ 1 ¦ 1 ¦ 0 ¦ ¦

+---------------------+-----+-----+-----+-------------------------------¦

¦ JNLE / JG ¦ 0 ¦ 0 ¦ 0 ¦ больше / не меньше или равны ¦

¦ ¦ 1 ¦ 0 ¦ 1 ¦ ¦

+-----------------------------------------------------------------------+

3) Команды, общие для знаковых и беззнаковых чисел:

+-------------------------------------------------------------------+

¦ мнемоника ¦ состояние флажков ¦ комментарий ¦

¦ команды +-------------------¦ ¦

¦ ¦ OF ¦ ZF ¦ PF ¦ SF ¦ ¦

+------------+----+----+----+----+----------------------------------¦

¦ JE / JZ ¦ - ¦ 1 ¦ - ¦ - ¦ равно / нуль ¦

+------------+----+----+----+----+----------------------------------¦

¦ JP / JPE ¦ - ¦ - ¦ 1 ¦ - ¦ есть паритет / паритет четный ¦

+------------+----+----+----+----+----------------------------------¦

¦ JO ¦ 1 ¦ - ¦ - ¦ - ¦ есть переполнение ¦

+------------+----+----+----+----+----------------------------------¦

¦ JS ¦ - ¦ - ¦ - ¦ 1 ¦ есть знак ¦

+------------+----+----+----+----+----------------------------------¦

¦ JNE / JNZ ¦ - ¦ 0 ¦ - ¦ - ¦ не равно / не нуль ¦

+------------+----+----+----+----+----------------------------------¦

¦ JNP / JPO ¦ - ¦ - ¦ 0 ¦ - ¦ нет паритета / паритет нечетный ¦

+------------+----+----+----+----+----------------------------------¦

¦ JNO ¦ 0 ¦ - ¦ - ¦ - ¦ нет переполнения ¦

+------------+----+----+----+----+----------------------------------¦

¦ JNS ¦ - ¦ - ¦ - ¦ 0 ¦ нет знака ¦

+-------------------------------------------------------------------+

4) Прочие команды:

JCXZ – переход на метку, если содержимое регистра CX равно нулю;

Форматы команд соответствуют командам безусловного перехода по однобайтовому смещению. То есть команда, на которую выполняется переход, должна находиться на расстоянии -128..+127 байт от команды, следующей за командой условного перехода.

Команда сравнения CMP.

Команда CMP выполняет вычитание второго операнда из первого, но нигде не запоминает результат операции и лишь изменяет состояние регистра флагов.

Формат команды:

CMP mem/reg1,mem/reg2

CMP mem/reg,data

Команды организации циклов.

Три команды управления циклами применяются для организации программных циклов. В них предусматривается использование регистра CX в качестве счетчика цикла.

В поле операнда команд управления циклами находится метка первой команды цикла (8-битовое смещение). Диапазон переходов этих команд составляет -128 ... +127 байт от следующей команды.

Команда LOOP производит декремент регистра CX и, если содержимое CX не равно нулю, происходит переход к началу цикла. В противном случае выполняется следующая по порядку команда.

Команды LOOPE/LOOPZ определяют одну и ту же машинную команду, которая производит декремент регистра CX, а затем передает управление в начало цикла, если содержимое CX не равно нулю и ZF=1. В противном случае выполняется следующая по порядку команда.

Команды LOOPNE/LOOPNZ также определяют одну и ту же машинную команду, которая производит декремент регистра CX, а затем передает управление в начало цикла, если содержимое CX не равно нулю и ZF=0. В противном случае выполняется следующая по порядку команда.

Пример программы:

mov CX, N

next:

<тело цикла>

sub CX, 1

jnz next

Последние две команды могут быть заменены командой LOOP next, однако следует помнить, что команда LOOP не изменяет значения флагов, в отличие от команды SUB.

Способы адресации данных в процессоре 8086

В командах обработки данных формируются адреса операндов, которые указывают местоположение данных в памяти. В командах управления определяются адреса команд, которым передается управление, т.е. адреса переходов. Способ определения адреса перехода или адреса операнда называется режимом адресации.

В процессоре 8086 используется семь способов адресации:

1. Регистровая адресация.

2. Непосредственная адресация.

3. Прямая адресация.

4. Косвенная регистровая адресация.

5. Адресация с базированием.

6. Адресация с индексированием.

7. Адресация с базированием и индексированием.

Микропроцессор выбирает способ адресации в зависимости от формата выполняемой команды. Например, при выполнении команды MOV AX,BX будет применена регистровая адресация, а при выполнении команды MOV AX,[BX] – косвенная.

Таблица режимов адресации

Адресация

Формат операнда

Сегментный регистр

1

Регистровая

Регистр

Не используется

2

Непосредственная

Константа

Не используется

3

Прямая

Смещение

или метка

DS

DS

4

Косвенная

регистровая

[BX]

[BP]

[DI]

[SI]

DS

SS

DS

DS

5

С базированием

[BX]+ смещение

[BP]+ смещение

DS

SS

6

С индексированием

[DI]+ смещение

[SI]+ смещение

DS

DS

7

С базированием и

индексированием

[BX]+[SI] + смещение

[BX]+[DI] + смещение

[BP]+[SI] + смещение

[BP]+[DI] + смещение

DS

DS

SS

SS

В таблице приведены форматы операндов языка Ассемблера для всех семи видов адресации, реализуемой МП. Для каждого формата указано, какой регистр сегмента будет использоваться для вычисления физического адреса. Во всех режимах предполагается доступ к сегменту данных, то есть регистром сегмента служит регистр DS. В тех случаях, когда используется регистр BP, предполагается доступ к сегменту стека, то есть регистром сегмента служит регистр SS.

Примечания:

  1. Компонент “смещение” при адресации по базе с индексированием не обязателен;

  2. Операнд может быть любым 8- или 16-битным регистром, кроме регистра IP;

  3. Операнд может быть 8- или 16-битным значением константы;

  4. Компонент “смещение” может быть 8- или 16-битным значением со знаком;

  5. При исполнении команд МП, манипулирующих строками, предполагается, что регистр DI указывает на ячейку дополнительного сегмента, а не на сегмент данных. Таким образом, в качестве регистра сегмента эти команды используют регистр ES. Все другие команды описываются по правилам, отраженным в этой таблице.

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

Регистровая адресация

При регистровой адресации МП извлекает операнд из регистра или загружает его в регистр. Например, MOV AX,CX копирует 16-битное содержимое CX в аккумулятор AX. Содержимое регистра CX не изменяется. В данном примере процессор использует регистровую адресацию для извлечения операнда-источника из регистра CX и загрузку его в приёмник AX.

Непосредственная адресация

Непосредственная адресация позволяет указывать пользователю 8- или 16-битное значение константы в качестве операнда-источника. Эта константа содержится в команде, куда она помещается компилятором, а не в регистре и не в ячейке памяти. Например, команда MOV CX,500 загружает константу 500 в регистр CX, а команда MOV CL,-30 помещает константу -30 в регистр CL.

Непосредственный операнд может быть идентификатором, определенным директивой EQU, поэтому допустима следующая форма записи:

K EQU 1024

………………

MOV CX, K

Прямая адресация (па)

При прямой адресации адрес ячейки памяти является составной частью команды (так же как при непосредственной адресации). Процессор добавляет этот исполнительный адрес к сдвинутому содержанию регистра DS и получает 20-разрядный физический адрес операнда. Обычно прямая адресация применяется, если операндом служит метка.

MOV AX , DATA – загружает содержимое DATA в AX.

MOV AX , TABLE TABLE

0001

BB 0002

AA 0003

0004

На рисунке показана схема исполнения команды MOV AX , TABLE. Процессор заполняет данные в память в обратном порядке, старшие байты данных располагаются в ячейках памяти со старшими адресами.

Косвенная регистровая адресация (кра).

При КРА исполнительный адрес операнда содержится в регистре BX, регистре-указателе базы BP или индексном регистре DI, SI. Косвенные регистровые операнды надо заключать в квадратные скобки, чтобы отличить их от регистров.

Команда MOV AX , [BX] загружает в AX содержимое ячейки памяти, адресуемой значением регистра BX.

MOV AX , [BX]

BX 0001 TABLE

0002

AX

Один из методов помещения адреса в регистр BX состоит в применении операции OFFSET к адресу ячейки памяти. Например, для загрузки слова из ячейки TABLE можно воспользоваться:

MOV BX , OFFSET TABLE

MOV AX , [BX]

Эти две команды выполняют те же действия, что MOV AX,TABLE с той разницей, что в первом случае предыдущее содержание BX уничтожается. Поэтому если нужен доступ лишь к одной ячейке TABLE, то разумней воспользоваться одной командой, однако для доступа к нескольким ячейкам лучше хранить исполнительный адрес в регистре, потому что содержанием регистра можно манипулировать, не извлекая каждый раз новый адрес.

Адресация с базированием (аб)

При АБ Ассемблер вычисляет ИА с помощью сложения значения сдвига и содержимого регистра BX или BP.

Регистр BX удобно использовать при доступе к структурированным записям данных, расположенных в различных областях памяти.

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

Предположим, требуется прочитать с диска учетные записи для ряда сотрудников. При этом каждая запись содержит табельный номер, номер отдела, возраст и т.д. Если номер отдела хранится в 5 и 6 байтах, а начальный адрес записи содержится в BX, то команда такого типа запишет в регистр AX номер отдела, в котором служит данный работник:

MOV AX , [BX] + 4 сдвиг

BX 001A

001B

AX 001C

001D

001E

001F

Ассемблер позволяет указывать адресуемые по базе операнды 3 способами:

  1. MOV AX , [BP] + 4

  2. MOV AX , [BP + 4]

  3. MOV AX , 4[BX]