Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

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

A DB?

B DW A

В примере ассемблер запишет в слово, выделенное, под переменную B, адрес переменной A, который становится начальным значением переменной B.

В правой части директивы DW можно указать любое число операндов, а также конструкцию повторения:

A DW 100, 3 DUP(?)

Директива DD(DefineDoubleWord, определить двойное слово) определяет переменную, под которую отводится двойное слово. Пере­менная имеет тип DWORD (значением константы является число 4).

Определение неинициализированной переменной:

A DD ?

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

Операндом директивы может быть константное выражение со значение от -231до 232-1.

B DD123456h

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

Операндом директивы может быть число в диапазоне от -215до 216-1. Все выражения вычисляются в области 16-битовых чисел (по модулю 216). Например, по директиве:

A DD 8000h+8002h

начальным значением переменной A будет число 2, а не число 10002h.

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

Конструкция повторения DUP:

DW 10 DUP(?), 12345h

Директива эквивалентности EQU(Equal, равно) позволяет определить константу и имеет следующий синтаксис:

<имя> EQU <операнд>

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

Если в правой части директивы указано имя регистра, переменной или константы, тогда имя слева объявляется синонимом данного имени и все последующие вхождения в текст программы этого имени-синонима ассемблер будет заменять на имя, указанное справа, например:

A DW ?

В EQU A

C DW В ; эквивалентно С DW A

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

SUMEQUAX

и далее использовать более наглядное имя.

Операндом директивы EQU может быть константное выражение, например:

N EQU 100

К EQU 2*N-1

Если в правой части директивы EQU находится константное выражение, тогда указанное слева имя принято называть именем константы. Значением такой константы объявляется значение выражения. Например, N – константа со значением 100, К – со значением 199. Все последующие вхождения в текст имени константы ассемблер будет заменять на значение этой константы.

Операндом может быть любой текст:

s EQU'Ошибка’

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

Директива присваиванияопределяет константу с именем, указанным в левой части и с числовым значением, равным значению выражения справа:

<имя> = <константное выражение>

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

C=10

A DW C ; эквивалентно A DW 10

C=C+2

В DB C ; эквивалентно В DB 12

3.3. Выражения

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

Константные выражения.Значениями константных выражений являются 16-битовые целые. К простейшим константным выражениям относятся:

  • число в диапазоне от -215до 216-1 (числа вне диапазона рассматриваются как ошибка);

  • символ (значением выражения является код символа);

  • строка из двух символов (значением является число-слово, составленное из кодов этих символов);

  • имя константы (значением выражения является значение константы).

Среди константных операторов (операторов с числовым значением) отметим оператор TYPE и арифметические операторы (k, k1 и k2 означают константные выражения):

  • одноместные плюс и минус: +k, -k;

  • операторы сложения и вычитания: k1+k2, k1-k2;

  • операторы умножения и деления: k1*k2, k1/k2, k1 MOD k2 (* – умножение, / – целочисленное деление, MOD – взятие остатка от деления).

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

К EQU 30

X DB (3*К-1)/2 DUP(?) ; массив из 44 байтов

В арифметических операциях вычисления выполняются в области 16-битовых чисел, т.е. от результата всегда берутся только последние 16 разрядов (остаток от деления на 216).

Адресные выражения.Значениями адресных выражений являются 16-битовые адреса, поэтому все операции также выполняются по модулю 216. К простейшим адресным выражениям относятся:

  • метка (имя команды) и имя переменной, описанные по директиве DB, DW или DD (значениями таких выражений являются адреса меток и имен);

  • счетчик размещения.

Счетчик размещенияобозначается символ «$» и определяет адрес того предложения, в котором он встретился. При трансляции ассемблер следит за тем, в ячейку с каким адресом должен попасть машинный эквивалент очередного предложения программы. При ссылках на адрес можно указывать символ «$». Поэтому в разных предложениях счетчик размещения обозначает различные адреса.

Например, если адрес переменной А равен 100h, тогда:

A DW $ ; эквивалентно A DW 100h

В DW $ ; эквивалентно В DW 102h

Счетчик размещения удобен для вычисления размера памяти, занимаемой массивом, например:

X DW 10 DUP(?)

SIZE EQU $-X ; SIZE = 20

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

Среди операторов, значением которых являются адреса, отметим операторы сложения и вычитания. Адресные выражения вида <имя>±<целое> используются для ссылок на безы­мянные ячейки памяти, как правило, элементы массивов. Например, в массиве:

A DB 0,1,2,3

именованным окажется только первый байт со значениями 0, а к остальным элементам массива нельзя будет обратиться по имени. Для доступа к таким ячейкам используются адрес­ные выражения указанного вида. Например, сослаться на байт со значением 1 можно с помощью выражения А+1.

Операция вычитания адреса из числа, а также сложение, умножение и деление адресов не имеют смысла и запрещены. Однако допускается вычитание адресов. В этом случае результатом будет являться константа – смещение одного адреса относительного другого. Адреса запрещено указывать в явном (числовом) виде. Если указано число, то оно всегда воспринимается как константа, а не как адрес.

Контрольные вопросы

  1. Опишите структуру команды на языке ассемблера.

  2. Приведите примеры объявления числовых и символьных данных на языке ассемблера.

  3. Перечислите допустимые операции над адресами.

  4. Приведите примеры адресных выражений.

4. Сегментированная модель памяти

4.1. Сегментирование адресов

Для работы с оперативной памятью используются шина адреса и шина данных. Физически память устроена таким образом, что возможна адресация как 16-битовых слов, так и отдельных байтов памяти. Ширина шины адреса определяет максимальный объём физической памяти, непосредственно адресуемой процессором. Из рассмотрения формата машинной команды становится понятно, что большой объем оперативной памяти ведет к увеличению размера команд. Для их уменьшения поступают следующим образом.

Оперативную память разделяют на логические участки – сегменты. Причем начальные адреса сегментов могут быть любыми, но размер любого сегмента не должен превосходить 2mячеек (m < k, k – разрядность шина адреса). Тогдаабсолютный(физический)адреснекоторой ячейки памяти A можно представить в виде суммы:

где B – база сегмента, к которому относится ячейка A, disp – относительный адрес ячейки, отсчитанный от начала сегмента (адреса В) или смещение(displacement).

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

Размер памяти в вычислительной системе на базе микропроцессора 8086 составляет 1 Мб, т.е. 220байтов (адреса 20-разрядные, k=20), а размер сегмен­тов не должен превышать 64 Кб, т.е. 216байтов (сме­щения 16-разрядные адреса, m=16). Адреса принято записывать в шестнадцатеричной форме, поэтому физические адреса для 20-разрядной шины адреса находятся в пределах:

00000h [физический адрес]FFFFFh

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

Источник: https://files.student-it.ru/previewfile/284711