Remkomplekty.ru

IT Новости из мира ПК
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Косвенный способ адресации ассемблер

Операнды в языке ассемблера

Операнд – объект, над которым выполняется машинная команда.

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

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

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

Под способами адресации понимаются существующие способы задания адреса хранения операндов:

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

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

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

  • 32-разрядные регистры ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP;
  • 16-разрядные регистры АХ, ВХ, СХ, DX, SI, DI, SP, ВР;
  • 8-разрядные регистры АН, AL, BH, BL, CH, CL, DH, DL;
  • сегментные регистры CS, DS, ,SS, ES, FS, GS.
  • прямую адресацию;
  • косвенную адресацию.

Прямая адресация : эффективный адрес определяется непосредственно полем смещения машинной команды, которое может иметь размер 8, 16 или 32 бита.

Ассемблер заменяет sum на соответствующий адрес, хранящийся в сегменте данных (по умолчанию адресуется регистром ds ) и значение, хранящееся по адресу sum , помещает в регистр eax .

Косвенная адресация в свою очередь имеет следующие виды:

  • косвенная базовая (регистровая) адресация;
  • косвенная базовая (регистровая) адресация со смещением;
  • косвенная индексная адресация;
  • косвенная базовая индексная адресация.

Косвенная базовая (регистровая) адресация. При такой адресации эффективный адрес операнда может находиться в любом из регистров общего назначения, кроме sp/esp и bp/ebp (это специфические регистры для работы с сегментом стека). Синтаксически в команде этот режим адресации выражается заключением имени регистра в квадратные скобки [].

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

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

Косвенная индексная адресация. Для формирования эффективного адреса используется один из регистров общего назначения, но обладает возможностью масштабирования содержимого индексного регистра.

Значение эффективного адреса второго операнда вычисляется выражением mas+( esi *4) и представляет собой смещение относительно начала сегмента данных.

Наличие возможности масштабирования существенно помогает в решении проблемы индексации при условии, что размер элементов массива постоянен и составляет 1, 2, 4 или 8 байт.

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

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

Эффективный адрес второго операнда формируется как esi+edx . Значение по этому адресу помещается в регистр eax.

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

Операндом является порт ввода-вывода.
Помимо адресного пространства оперативной памяти микропроцессор поддерживает адресное пространство ввода-вывода, которое используется для доступа к устройствам ввода-вывода. Объем адресного пространства ввода-вывода составляет 64 Кбайт. Для любого устройства компьютера в этом пространстве выделяются адреса. Конкретное значение адреса в пределах этого пространства называется портом ввода-вывода. Физически порту ввода-вывода соответствует аппаратный регистр (не путать с регистром микропроцессора), доступ к которому осуществляется с помощью специальных команд ассемблера in и out .

Регистры, адресуемые с помощью порта ввода-вывода, могут иметь разрядность 8, 16 или 32 бит, но для конкретного порта разрядность регистра фиксирована. В качестве источника информации или получателя применяются регистры-аккумуляторы eax , ax , al . Выбор регистра определяется разрядностью порта. Номер порта может задаваться непосредственным операндом в командах in и out или значением в регистре dx . Последний способ позволяет динамически определить номер порта в программе.

Счетчик адреса – специфический вид операнда. Он обозначается знаком $. Специфика этого операнда в том, что когда транслятор ассемблера встречает в исходной программе этот символ, он подставляет вместо него текущее значение счетчика адреса (регистр EIP ). Значение счетчика адреса представляет собой смещение текущей машин­ной команды относительно начала сегмента кода, адресуемого сегментным регистром CS . При обработке транслятором очередной команды ассемблера счетчик адреса увеличивается на длину сформированной машинной команды. Обработка директив ассемблера не вле­чет за собой изменения счетчика. В качестве примера использования в команде значения счетчика адреса можно привести следующий фрагмент:

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

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

Записи (аналогично структурному типу) используются для доступа к битовому полю некоторой записи. Для доступа к битовому полю записи используется директива RECORD .

Операторы в языке ассемблера

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

Режимы адресации и форматы машинных команд

Микропроцессор Intel предоставляет множество способов доступа к операндам. Операнды могут содержаться в регистрах, самих командах, в памяти или в портах ввода-вывод. Режимы адресации разделяются на семь групп:

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

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

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

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

5. Адресация по базе.

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

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

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

То ассемблер закодирует оба операнда (AX, BX) для регистровой адресации. Если же поместить регистр BX в квадратные скобки:

То Ассемблер закодирует операнд-источник для косвенной регистровой адресации.

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

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

1) Формат «регистр-регистр» (2байта):

КОП d w 11 reg1 reg2

7 . 2 1 0 7 6 5 4 3 2 1 0

Команды этого формата описывают обычно действие reg1:=reg1‑reg2 или reg2:=reg2‑reg1. Поле КОП первого байта указывает на операцию (‑), которую надо выполнить. Бит w определяет размер операндов, а бит d указывает, в какой из регистров записывается результат:

w = 1 — слова d = 1 — reg1:=reg1‑reg2

= 0 — байты = 0 — reg2:=reg2‑reg1

Во втором байте два левых бита фиксированы (для данного формата), а трехбитовые поля reg1 и reg2 указывают на регистры, участвующие в операции, согласно следующей таблице:

2) Формат «регистр-память» (2-4 байта):

КОП |d|w| |mod|reg|mem| |адрес (0-2 байта)

Эти команды описывают операции reg:=reg‑mem или mem:=mem‑reg. Бит w первого байта определяет размер операндов (см. выше), а бит d указывает, куда записывается результат: в регистр (d=1) или в ячейку памяти (d=0). Трехбитовое поле reg второго байта указывает операнд-регистр (см. выше), двухбитовое поле mod определяет, сколько байтов в команде занимает операнд-адрес (00 — 0 байтов, 01 — 1 байт, 10 — 2 байта), а трехбитовое поле mem указывает способ модификации этого адреса. В следующей таблице указаны правила вычисления исполнительного адреса в зависимости от значений полей mod и mem (a8 — адрес размером в байт, a16 — адрес размером в слово):

Читать еще:  Восстановление mac адреса

mem mod 00 01 10

000 [BX]+[SI] [BX]+[SI]+a8 [BX]+[SI]+a16

001 [BX]+[DI] [BX]+[DI]+a8 [BX]+[DI]+a16

010 [BP]+[SI] [BP]+[SI]+a8 [BP]+[SI]+a16

011 [BP]+[DI] [BP]+[DI]+a8 [BP]+[DI]+a16

100 [SI] [SI]+a8 [SI]+a16

101 [DI] [DI]+a8 [DI]+a16

110 a16 [BP]+a8 [BP]+a16

111 [BX] [BX]+a8 [BX]+a16

Замечания. Если в команде не задан адрес, то он считается нулевым.

Если адрес задан в виде байта (a8), то он автоматически расширяется со знаком до слова (a16). Случай mod=00 и mem=110 указывает на отсутствие регистров-модификаторов, при этом адрес должет иметь размер слова (адресное выражение [BP] ассемблер транслирует в mod=01 и mem=110 при a8=0). Случай mod=11 соответствует формату «регистр-регистр».

3) Формат «регистр-непосредственный операнд» (3-4 байта):

КОП |s|w| |11|КОП»|reg| |непосред.операнд (1-2 б)

Команды этого формата описывают операции reg:=reg‑immed (immed — непосредственный операнд). Бит w указывает на размер операндов, а поле reg — на регистр-операнд (см. выше). Поле КОП в первом байте определяет лишь класс операции (например, класс сложения), уточняет же операцию поле КОП» из второго байта. Непосредственный операнд может занимать 1 или 2 байта — в зависимости от значения бита w, при этом операнд-слово записывается в команде в «перевернутом» виде. Ради экономии памяти в ПК предусмотрен случай, когда в операции над словами непосредственный операнд может быть задан байтом (на этот случай указывает 1 в бите s при w=1), и тогда перед выполнением операции байт автоматически расширяется (со знаком) до слова.

4) Формат «память-непосредственный операнд» (3-6 байтов):

КОП |s|w| |mod|КОП»|mem| |адрес (0-2б)| |непоср.оп (1-2б)|

Команды этого формата описывают операции типа mem:=mem‑immed. Смысл всех полей — тот же, что и в предыдущих форматах.

Помимо рассмотренных в ПК используются и другие форматы команды с двумя операндами; так, предусмотрен специальный формат для команд, один из операндов которых фиксирован (обычно это регистр AX). Имеют свои форматы и команды с другим числом операндов.

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

MOV op1,op2 (op1:=op2)

Анализируя типы операндов, ассемблер сам выбирает подходящую машинную команду.

Регистры указываются своими именами, например:

MOV AX,SI ;оба операнда — регистры

Непосредственные операнды задаются константными выражениями (их значениями являются константы-числа), например:

MOV BH,5 ;5 — непосредственный операнд

MOV DI,SIZE_X ;SIZE_X (число байтов, занимаемых переменной X) — непосредственный операнд

Адреса описываются адресными выражениями (например, именами переменных), которые могут быть модифицированы по одному или двум регистрам; например, в следующих командах первые операнды задают адреса:

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

MOV AH,5 ;пересылка байта, т.к. AH — байтовый регистр

MOV AX,5 ;пересылка слова, т.к. AX — 16-битовый регистр;(операнд 5 может быть байтом и словом, по нему ;нельзя определить размер пересылаемой величины)

MOV [BX],300 ;пересылка слова, т.к. число 300 не может быть байтом.

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

MOV DS,AX ;оба операнда имеют размер слова

MOV CX,BH ;ошибка: регистры CX и BH имеют разные размеры

MOV DL,300 ;ошибка: DL — байтовый регистр, а число 300 не

;может быть байтом

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

Здесь число 5 может быть и байтом, и словом, а адрес из регистра BX может указывать и на байт памяти, и на слово. В подобных ситуациях ассемблер фиксирует ошибку. Чтобы избежать ее, надо уточнить тип одного из операндов с помощью оператора с названием PTR:

MOV BYTE PTR [BX],5 ;пересылка байта

MOV WORD PTR [BX],5 ;пересылка слова

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

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

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

нельзя, т.к. ее операнды имеют разный размер. Эту команду следует записать несколько иначе:

MOV AH,BYTE PTR X

Здесь конструкция BYTE PTR X означает адрес X, но уже рассматриваемый не как адрес слова, а как адрес байта. (Напомним, что с одного и того же адреса может начинаться байт, слово и двойное слово; оператор PTR уточняет, ячейку какого размера мы имеем в виду.)

Ассемблеры. Режимы адресации;

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

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

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

Ассемблеры – машинно-ориентированные языки (состоят из мнемокодов-команд процессора).

Одним из аспектов машинной зависимости является имеющиеся различия в форматах машинных команд и кодах операций. С другой стороны некоторые средства языка не имеют прямой связи со структурой компьютера. Их выбор является произвольным и определяется разработчиком языка. Многие Ассемблеры представляют гибкие средства обработки исходной программы и соответствующего ей объектного кода.

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

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

Для перевода исходной программы в ее объектное преставление необходимо:

1) Преобразовать мнемонические коды операций в их эквиваленты на машинном языке.

2) Преобразовать символические операнды в эквивалентные им машинные адреса.

3) Построить машинные команды в соответствующем формате.

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

5) Записать объектную программу и выдать листинг.

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

Основной задачей первого просмотра является поиск символических имен и назначение им адресов.

Фрагменты программы, содержащие ссылки “вперед” запоминаются во время первого просмотра. Дополнительный просмотр таких заполненных определений выполняются по мере продвижения этого процесса ассемблирования, по завершению этого процесса выполняется обычный 2-й просмотр. Фактическая трансляция выполняется во время второго просмотра.

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

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

Не обязательно внутри объектной программы сгенерированные машинные коды и данные должны располагаться в том же порядке, в котором они были в исходном тексте. Многие Ассемблеры предоставляют средства, позволяющие создавать несколько независимых частей объектной программы. Часть программы, которая сохраняет после Ассемблирования свою индивидуальность и может загружаться и перемещаться независимо от других, называется управляющей секцией (УС)

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

Читать еще:  Password protect usb торрент

Для этого надо определить 2 типа записей:

— Запись-определение (содержит информацию о внешних именах, определенных в данной управляющей секции)

— Запись–ссылка (содержит список имен, используемых в качестве внешних ссылок)

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

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

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

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

Команды центрального процессора рассматриваются как операционные ресурсы нижнего уровня доступные программисту.

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

Главной особенностью языка ассемблера является использование одного названия операций для всех семантически идентичных действий независимо от форматов и размеров данных.

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

Режимы адресаций можно разделить на 7 групп:

1) регистровая адресация (mov AX,BX) при которой микропроцессор извлекает операнд из регистра и помещает результат в регистр.

2) непосредственная адресация, которая позволяет указывать значение константы в качестве операнда источника mov cx,25h

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

4) косвенно регистровая, при которой исполнительный адрес содержится в базовом регистре BX, указателе базы BP или индексном регистре SI или DI (mov DI, offset DAN mov AL, [BX]). Косвенные регистровые операнды заключаются в квадратные скобки.

5) адресация по базе (mov AL, [BX]+4) Ассемблер вычисляет исполнительный адрес с помощью сложения содержимого регистров BX или BP, в которые загружается базовый адрес со значением сдвига.

6) прямая адресация с индексированием

mov AL, TABL[DI]) загрузили 6й элемент массива

Исполнительный адрес вычисляется как сумма значений сдвига и содержимого индексного регистра SI или DI.

7) адресация по базе с индексированием — адрес высчитывается как сумма значений базового регистра, индексного регистра и сдвига (mov AX,AL[BX][DX]

Адресация регистров и ячеек памяти в Ассемблере

При программировании на языке ассемблер используются неявный, непосредственный, прямой и косвенный методы адресации; причем для адресации регистров в МПП— только прямой, а для адресации ячеек ОП — прямой, косвенный, и смешанный непосредственный методы. Рассмотрим их на примере адресации второго операнда в команде MOV (переслать).

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

Величина операнда i (impendence) непосредственно указывается в поле команды и может быть задана числом в десятичной, двоичной и шестнадцатеричной системах счисления (последний символ числа должен быть, соответственно, D (или никакой), B и H) или идентификатором, а также простым выражением, в котором указанные элементы связаны символами арифметических операций: +, -, * и /. Идентификатор (с соответствующим именем, например, const) должен быть предварительно описан в программе директивой типа: const equ 1024 или const = 1024.

Примеры непосредственной адресации:

MOV AX, 1024D; MOV AL, 64; MOV AX, const; MOV AX, 156*10H/2

Следует помнить, что диапазон чисел, посылаемых в регистры, ограничивается вместимостью последнего: в 1-байтовый регистр (AH, AL, BH и т.д.) можно посылать числа в диапазоне от 0 до +255 (целое без знака) или от –128 до +127 (целое со знаком); в 2-байтовый регистр (AX, BX, CX и т.д.)— от 0 до +65 535 (целое без знака) или от –32 768 до +32 767 (целое со знаком).

Прямая адресация регистров МПП

В качестве адреса операнда указывается имя регистра (его символьное обозначение: AX, AL, AH, BX, BL и т.д.). Примеры:

MOV AX, BX; MOV BX, DX; MOV AH, BL

Необходимо следить, чтобы разрядность второго операнда (его регистра) соответствовала разрядности принимающего регистра.

Адресация ячеек ОП

Напомним, что абсолютный (полный, физический) адрес (Aабс) в общем случае является суммой адресов сегмента (Aсегм) и исполнительного адреса (Aисп), в свою очередь формируемого как сумма максимум 3-х адресов: смещения (Aсмещ), базы (Aбаз), и индекса (Aинд), то есть:

Прямая адресация ячеек ОП имеет несколько вариантов:

l прямая обычная: MOV AX, pole.

Pole — символьное имя переменной X, для которой в ОП были предварительно отведены (или зарезервированы) ячейки памяти директивами типа:

pole DB X, pole DW X и т.п.

В команде в качестве Aисп берется Aсмещ первой ячейки поля, отведенной для переменной X.

l прямая с индексированием: MOV AX, pole[SI].

В команде в качестве Aисп берется Aисп = Aсмещ + Aинд

Aинд находится в регистре SI.

l прямая с базированием: MOV AX, pole[BX].

Aбаз находится в регистре BX.

l прямая с индексированием и базированием:
MOV AX, pole[SI+BX].

Существуют два варианта косвенной адресации ячеек ОП:

l косвенная обычная: MOV AX, [BX].

Исполнительный адрес извлекается из регистра BX, то есть Aисп = [BX].

l косвенная с индексированием: MOV AX, [BX+SI].

Исполнительный адрес берется в виде суммы адресов, находящихся в регистрах BX и SI, Aисп = [BX] + [SI].

Смешанная непосредственная адресация ячеек ОП имеет несколько вариантов:

l непосредственная обычная: MOV AX, offset pole.

В качестве операнда берется непосредственно смещение адреса первой ячейки поля памяти, отведенного для переменной X; offset указывает, что берется не значение переменной X, а именно смещение ее адреса;

l непосредственная с индексированием:

l MOV AX, [SI+const].

В качестве операнда берется сумма значения, хранящегося в регистре SI, и величины const; const может быть задана числом, идентификатором, смещением адреса переменной (offset pole) или их комбинацией — простым выражением;

l непосредственная с базированием:

l MOV AX, [BX+const].

Аналогично предыдущему варианту, но регистр SI замещен BX;

l непосредственная с базированием и индексированием:
MOV AX, pole[SI+BX+const].

Аналогично предыдущему, но вместо содержимого одного регистра берется сумма содержимого регистров BX и SI.

Почти все команды ассемблера за редким исключением (исключения: POP, PUSH, CALL, RET, IRET) в качестве Aсегм обычно используют по умолчанию адрес, находящийся в регистре DS (в исполняемых программах типа .COM — в регистре CS); но регистр сегмента может быть задан и явно, например: MOV AX, EX:pole; MOV AX, SS:[SI] и т.п.

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

Команды POP, PUSH, CALL, RET, IRET используют сегмент стека (регистр SS).

Основные команды языка ассемблер

По назначению можно выделить команды (в скобках приводятся примеры мнемонических кодов операций команд ассемблера ПК типа IBM PC):

l пересылки данных (MOV — переслать, XCHG — обменять, IN — ввести в микропроцессор, OUT — вывести из микропроцессора и другие);

l выполнения арифметических операций (ADD и ADC — сложения и сложения с переносом, SUB и SBB — вычитания и вычитания с заемом, MUL и IMUL — умножения без знака и со знаком, DIV и IDIV — деления без знака и со знаком, CMP — сравнения и другие );

l выполнения логических операций (OR, AND, NOT, XOR, TEST и другие);

Читать еще:  Шина адреса это в информатике

l передачи управления (ветвления программы: JMP — безусловного перехода, CALL — вызова процедуры, RET — возврата из процедуры, J* — условного перехода, LOOP — управления циклом и т.д.);

l обработки строк символов (MOVS — пересылки, CMPS — сравнения, LODS — загрузки, SCAS — сканирования. Эти команды обычно используются с префиксом (модификатором повторения) REP;

l прерывания работы программы (INT — программные прерывания, INTO — условного прерывания при переполнении, IRET — возврата из прерывания);

l управления микропроцессором (ST* и CL* — установки и сброса флагов, HLT — останова, WAIT — ожидания, NOP — холостого хода и другие).

С полным списком команд ассемблера можно познакомиться в работах [1, 8, 71].

Команды пересылки данных

l MOV dst, src — пересылка данных (mov — переслать из src в dst).

Пересылает один байт (если src и dst имеют формат байта) или одно слово (если src и dst имеют формат слова) между регистрами или между регистром и памятью, а также заносит непосредственное значение в регистр или в память[34].

Операнды dst и src должны иметь одинаковый формат — байт или слово.

Src могут иметь тип: r (register) — регистр, m (memory) — память, i (impedance) — непосредственное значение.

Dst могут быть типа r, m.

Нельзя в одной команде использовать операнды: rsegm совместно с i; два операнда типа m, два операнда типа rsegm). Операнд i может быть и простым выражением:

mov AX, (152 + 101B) / 15

Вычисление выражения выполняется только при трансляции. Флаги не меняет.

l PUSH src — занесение слова в стек (pushпротолкнуть; записать в стек изsrc). Помещает в вершину стека содержимое src — любого 16-битового регистра (в том числе и сегментного) или двух ячеек памяти, содержащих 16-битовое слово. Флаги не меняются;

l POP dst — извлечение слова из стека (pop— вытолкнуть; считать из стека в dst). Снимает слово с вершины стека и помещает его в dst — любой 16-битовый регистр (в том числе и сегментный) или в две ячейки памяти. Флаги не меняются.

В командах PUSH и POP операнды dst и src могут быть только типов r и m.

Арифметические команды

Операнды могут быть двоичные (8 или 16 битов, целые, со знаком или без знака), двоично-десятичные (от 1 до 255 байтов, без знака, в упакованном или распакованном (ASCII-коды) форматах). Машина не обращает внимания на формат и обращается с ними формально, как с двоичными числами в дополнительном коде. Но для десятичной арифметики после операции требуется коррекция (операции только над одним байтом).

wiki.vspu.ru

портал образовательных ресурсов

Содержание

Введение в Ассемблер. Работа с регистрами. Адресация и команды пересылки данных. Арифметические операции с целыми числами

Цели:

Основная нагрузка при работе компьютера ложится на процессор и память. Процессор выполняет команды, хранящиеся в памяти. В памяти хранятся также и данные. Между процессором и памятью происходит непрерывный обмен информацией. Процессор имеет свою небольшую память, состоящую из регистров. Команда процессора, использующая находящиеся в регистрах данные, выполняется много быстрее аналогичных команд над данными в памяти. Поэтому часто для того, чтобы выполнить какую-либо команду, данные для неё предварительно помещают в регистры. Результат команды можно при необходимости поместить обратно в память. Обмен данными между памятью и регистрами осуществляют команды пересылки. Кроме этого, можно обмениваться данными между регистрами, посылать и получать данные от внешних устройств. В регистр и ячейку памяти можно посылать и непосредственный операнд – число. Кроме этого имеются команды, с помощью которых можно помещать и извлекать данные из стека – специальной области памяти, используемой для хранения адресов возврата из функций, передаваемых в функцию параметров и локальных переменных.

Адресация и выделение памяти

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

Здесь используется доступ к переменной типа BYTE по указателю – структура BYTE PTR [EAX]. Немного позже мы увидим, как этот прием используется при написании программ.

Задания.

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

Доступ к переменной по указателю используется и в языках высокого уровня (очень часто – при создании динамических массивов).

Указатель – это переменная, которая содержит адрес другой переменной (говорят, что указатель указывает на переменную того типа, адрес которой он содержит). Существует одноместная (унарная, т.е. для одного операнда) операция взятия адреса переменной & (амперсанд, как в названии мультфильма Tom&Jerry). Если имеем объявление int a, то можно определить адрес этой переменной: &a. Если Pa – указатель, который будет указывать на переменную типа int, то можно записать: Pa=&a. Существует унарная операция * (она называется операцией разыменования), которая действует на переменную, содержащую адрес объекта, т.е. на указатель. При этом извлекается содержимое переменной, адрес которой находится в указателе. Если Pa=&a, то, воздействуя на обе части операцией * получим (по определению этой операции): *Pa=a. Исходя из этого, указатель объявляется так:

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

На листинге 4 представлена программа, позволяющая получать адреса элементов массивов разных типов средствами Cи. Обратите внимание на значения соседних адресов элементов массива.

Один из наиболее часто встречающихся случаев – использование указателей для динамического выделения памяти при создании массивов (листинг 5).

Задание. Выведите на экран адреса элементов массива, созданного в программе, показанной на листинге 5. Попробуйте создать динамический массив типа double, заполнить его, вывести на печать элементы массива и их адреса.

Арифметические операции над целыми числами

Сложение и вычитание целых чисел

Рассмотрим 3 основные команды сложения. Команда INC осуществляет инкремент, т.е. увеличение содержимого операнда на 1, например, INC EAX. Команда INC устанавливает флаги OF, SF, ZF, AF, PF в зависимости от результатов сложения. Команда ADD осуществляет сложение двух операндов. Результат пишется в первый операнд (приемник). Первый операнд может быть регистром или переменной. Второй операнд – регистром, переменной или числом. Невозможно, однако, осуществлять операцию сложения одновременно над двумя переменными. Команда действует на флаги CF, OF, SF, ZF, AF, PF. Её можно использовать для знаковых и для беззнаковых чисел. Команда ADC осуществляет сложение двух операндов подобно команде ADD и флага (бита) переноса. С её помощью можно осуществлять сложение чисел, размер которых превышает 32 бита или изначально длина операндов превышает 32 бита.

Умножение целых чисел

В отличие от сложения и вычитания умножение чувствительно к знаку числа, поэтому существует две команды умножения: MUL – для умножения беззнаковых чисел, IMUL – для умножения чисел со знаком. Единственным оператором команды MUL может быть регистр или переменная. Здесь важен размер этого операнда (источника).

Команда IMUL имеет 3 различных формата. Первый формат аналогичен команде MUL. Остановимся на двух других форматах.

operand1 должен быть регистр, operand2 может быть числом, регистром или переменной. В результате выполнения умножения (operand1 умножается на operand2, и результат помещается в operand1) может получиться число, не помещающееся в приемнике. В этом случае флаги CF и AF будут равны 1 (0 в противном случае).

В данном случае operand2 (регистр или переменная) умножается на operand3 (число) и результат заносится в operand1 (регистр). Если при умножении возникнет переполнение, т.е. результат не поместится в приемник, то будут установлены флаги CF и OF. Применение команд умножения приведено на листинге 8.

Листинг 8. Применение команд умножения

Деление целых чисел

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

Команда знакового деления IDIV полностью аналогична команде DIV. Существенно, что для команд деления значения флагов арифметических операций не определены. В результате деления может возникнуть либо переполнение, либо деление на 0. Обработку исключения должна обеспечить операционная система.

Ссылка на основную публикацию
Adblock
detector