37615

Программирование на языке ассемблера для микропроцессоров фирмы Intel

Конспект

Информатика, кибернетика и программирование

Программист или любой другой пользователь может использовать любые высокоуровневые средства вплоть до программ построения виртуальных миров и возможно даже не подозревать что на самом деле компьютер выполняет не команды языка на котором написана его программа а их трансформированное представление в форме скучной и унылой последовательности команд совсем другого языка машинного. шесть регистров сегментов: cs ds ss es fs gs; регистры состояния и управления: регистр флагов eflags flags; регистр указателя команды eip ip. Его...

Русский

2013-09-24

411.5 KB

37 чел.

ВВЕДЕНИЕ

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

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

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

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

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

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

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

тема 1: Оперативная память. Регистры общего назначения. Сегментные регистры. Указатель команд. Регистр флагов.

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

  •  16 пользовательских регистров; 
  •  16 системных регистров. 

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

1.1 Пользовательские регистры

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

  •  восемь 32-битных регистров, которые могут использоваться программистами для хранения данных и адресов (их еще называют регистрами общего назначения (РОН)):
    •  eax/ax/ah/al;
    •  ebx/bx/bh/bl;
    •  edx/dx/dh/dl;
    •  ecx/cx/ch/cl;
    •  ebp/bp;
    •  esi/si;
    •  edi/di;
    •  esp/sp.
  •  шесть регистров сегментов: cs, ds, ss, es, fs, gs;
  •  регистры состояния и управления:
    •  регистр флагов eflags/flags;
    •  регистр указателя команды eip/ip.

Почему многие из этих регистров приведены с наклонной разделительной чертой?
Нет, это не разные регистры - это части одного большого 32-разрядного регистра. Их можно использовать в программе как отдельные объекты.  Так сделано для обеспечения работоспособности программ, написанных для младших 16-разрядных моделей микропроцессоров фирмы Intel, начиная с i8086. Микропроцессоры i486 и Pentium имеют в основном 32-разрядные регистры. Их количество, за исключением сегментных регистров, такое же, как и у i8086, но размерность больше, что и отражено в их обозначениях - они имеют приставку
e (Extended).

Рисунок 1- Пользовательские регистры микропроцессоров i486 и Pentium 

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

Все регистры этой группы позволяют обращаться к своим
“младшим” частям (
рисунок 1). Рассматривая этот рисунок, заметьте, что использовать для самостоятельной адресации можно только младшие 16 и 8-битные части этих регистров. Старшие 16 бит этих регистров как самостоятельные объекты недоступны. Это сделано, как мы отметили выше, для совместимости с младшими 16-разрядными моделями микропроцессоров фирмы Intel.  Перечислим регистры, относящиеся к группе регистров общего назначения. Так как эти регистры физически находятся в микропроцессоре внутри арифметико-логического устройства (АЛУ), то их еще называют регистрами АЛУ:

  •  eax/ax/ah/al (Accumulator register) — аккумулятор.
    Применяется для хранения промежуточных данных. В некоторых командах использование этого регистра обязательно;
  •  ebx/bx/bh/bl (Base register) — базовый регистр.
    Применяется для хранения базового адреса некоторого объекта в памяти;
  •  ecx/cx/ch/cl (Count register) — регистр-счетчик.
    Применяется в командах, производящих некоторые повторяющиеся действия. Его использование зачастую неявно и скрыто в алгоритме работы соответствующей команды.
    К примеру, команда организации цикла
    loop кроме передачи управления команде, находящейся по некоторому адресу, анализирует и уменьшает на единицу значение регистра ecx/cx;
  •  edx/dx/dh/dl (Data register) — регистр данных.
    Так же, как и регистр eax/ax/ah/al, он хранит промежуточные данные. В некоторых командах его использование обязательно; для некоторых команд это происходит неявно.

Следующие два регистра используются для поддержки так называемых цепочечных операций, то есть операций, производящих последовательную обработку цепочек элементов, каждый из которых может иметь длину 32, 16 или 8 бит:

  •  esi/si (Source Index register) — индекс источника.
    Этот регистр в цепочечных операциях содержит текущий адрес элемента в цепочке-источнике;
  •  edi/di (Destination Index register) — индекс приемника (получателя).
    Этот регистр в цепочечных операциях содержит текущий адрес в цепочке-приемнике.

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

  •  esp/sp (Stack Pointer register) — регистр указателя стека.
    Содержит указатель вершины стека в текущем сегменте стека.
  •  ebp/bp (Base Pointer register) — регистр указателя базы кадра стека.

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

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

В программной модели микропроцессора имеется шесть сегментных регистров: cs, ss, ds, es, gs, fs. Их существование обусловлено спецификой организации и использования оперативной памяти микропроцессорами Intel. Она заключается в том, что микропроцессор аппаратно поддерживает структурную организацию программы в виде трех частей, называемых сегментами. Соответственно, такая организация памяти называется сегментной.

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

  1.  Сегмент кода. Содержит команды программы.
    Для доступа к этому сегменту служит регистр
    cs (code segment register) — сегментный регистр кода. Он содержит адрес сегмента с машинными командами, к которому имеет доступ микропроцессор (то есть эти команды загружаются в конвейер микропроцессора).
  2.  Сегмент данных. Содержит обрабатываемые программой данные.
    Для доступа к этому сегменту служит регистр
    ds (data segment register) — сегментный регистр данных, который хранит адрес сегмента данных текущей программы.
  3.  Сегмент стека. Этот сегмент представляет собой область памяти, называемую стеком.
    Работу со стеком микропроцессор организует по следующему принципу:
    последний записанный в эту область элемент выбирается первым. Для доступа к этому сегменту служит регистр ss (stack segment register) — сегментный регистр стека, содержащий адрес сегмента стека.
  4.  Дополнительный сегмент данных.
    Неявно алгоритмы выполнения большинства машинных команд предполагают, что обрабатываемые ими данные расположены в сегменте данных, адрес которого находится в сегментном регистре
    ds.
    Если программе недостаточно одного сегмента данных, то она имеет возможность использовать еще три дополнительных сегмента данных. Но в отличие от основного сегмента данных, адрес которого содержится в сегментном регистре
    ds, при использовании дополнительных сегментов данных их адреса требуется указывать явно с помощью специальных префиксов переопределения сегментов в команде.
    Адреса дополнительных сегментов данных должны содержаться в регистрах
    es, gs, fs (extension data segment registers).

1.4 Регистры состояния и управления

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

  •  регистр флагов eflags/flags;
  •  регистр указателя команды eip/ip.

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

eflags/flags (flag register) — регистр флагов. Разрядность eflags/flags — 32/16 бит. Отдельные биты данного регистра имеют определенное функциональное назначение и называются флагами. Младшая часть этого регистра полностью аналогична регистру flags для i8086. На рисунке 2 показано содержимое регистра eflags.

Рисунок 2- Содержимое регистра eflags 

Исходя из особенностей использования, флаги регистра eflags/flags можно разделить на три группы:

  •  8 флагов состояния. Эти флаги могут изменяться после выполнения машинных команд.
    Флаги состояния регистра eflags отражают особенности результата исполнения арифметических или логических операций. Это дает возможность анализировать состояние вычислительного процесса и реагировать на него с помощью команд условных переходов и вызовов подпрограмм. В таблице 1 приведены флаги состояния и указано их назначение;
  •  1 флаг управления. Обозначается df (Directory Flag).
    Он находится в 10-м бите регистра
    eflags и используется цепочечными командами. Значение флага df определяет направление поэлементной обработки в этих операциях: от начала строки к концу (df = 0) либо наоборот, от конца строки к ее началу (df = 1).
    Для работы с флагом
    df существуют специальные команды: cld (снять флаг df) и std (установить флаг df).
    Применение этих команд позволяет привести флаг
    df в соответствие с алгоритмом и обеспечить автоматическое увеличение или уменьшение счетчиков при выполнении операций со строками;
  •  5 системных флагов, управляющих вводом/выводом, маскируемыми прерываниями, отладкой, переключением между задачами и виртуальным режимом 8086.
    Прикладным программам не рекомендуется модифицировать без необходимости эти флаги, так как в большинстве случаев это приведет к прерыванию работы программы. В
    таблице 2 перечислены системные флаги, их назначение.

Таблица 1- Флаги состояния

Мнемоника флага

Флаг

Номер бита в eflags

Содержание и назначение

cf

Флаг переноса
(Carry Flag)

0

1 — арифметическая операция произвела перенос из старшего бита результата. Старшим является 7, 15 или 31-й бит в зависимости от размерности операнда;
0 — переноса не было

pf

Флаг паритета
(Parity Flag)

2

1 — 8 младших разрядов (этот флаг — только для 8 младших разрядов операнда любого размера) результата содержат четное число единиц;
0 — 8 младших разрядов результата содержат нечетное число единиц

af

Вспомогательный флаг переноса
(Auxiliary carry Flag)

4

Только для команд работающих с BCD-числами. Фиксирует факт заема из младшей тетрады результата:
1 — в результате операции сложения был произведен перенос из разряда 3 в старший разряд или при вычитании был заем в разряд 3 младшей тетрады из значения в старшей тетраде;
0 — переносов и заемов в(из) 3 разряд(а) младшей тетрады результата не было

zf

Флаг нуля (Zero Flag)

6

1 — результат нулевой;
0 — результат ненулевой

sf

Флаг знака
(Sign Flag)

7

Отражает состояние старшего бита результата (биты 7, 15 или 31 для 8, 16 или 32-разрядных операндов соответственно):
1 — старший бит результата равен 1;
0 — старший бит результата равен 0

of

Флаг переполнения
(Overflow Flag)

11

Флаг of используется для фиксирования факта потери значащего бита при арифметических операциях:
1 — в результате операции происходит перенос (заем) в(из) старшего, знакового бита результата (биты 7, 15 или 31 для 8, 16 или 32-разрядных операндов соответственно);
0 — в результате операции не происходит переноса (заема) в(из) старшего, знакового бита результата

iopl

Уровень Привилегий ввода-вывода
(Input/Output Privilege Level)

12, 13

Используется в защищенном режиме работы микропроцессора для контроля доступа к командам ввода-вывода в зависимости от привилегированности задачи

nt

флажок вложенности задачи
(Nested Task)

14

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

Таблица 2- Системные флаги

Мнемоника флага

Флаг

Номер бита в eflags

Содержание и назначение

tf

Флаг трассировки
(Trace Flag)

8

Предназначен для организации пошаговой работы микропроцессора.
1 — микропроцессор генерирует прерывание с номером 1 после выполнения каждой машинной команды. Может использоваться при отладке программ, в частности отладчиками;
0 — обычная работа

if

Флаг прерывания
(Interrupt enable Flag)

9

Предназначен для разрешения или запрещения (маскирования) аппаратных прерываний (прерываний по входу INTR).
1 — аппаратные прерывания разрешены;
0 — аппаратные прерывания запрещены

rf

Флаг возобновления
(Resume Flag)

16

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

vm

Флаг виртуального
(Virtual 8086 Mode)

17

Признак работы микропроцессора в режиме виртуального 8086.
1 — процессор работает в режиме виртуального 8086;
0 — процессор работает в реальном или защищенном режиме

ac

Флаг контроля выравнивания
(Alignment Check)

18

Предназначен для разрешения контроля выравнивания при обращениях к памяти. Используется совместно с битом am в системном регистре cr0. К примеру, Pentium разрешает размещать команды и данные с любого адреса. Если требуется контролировать выравнивание данных и команд по адресам кратным 2 или 4, то установка данных битов приведет к тому, что все обращения по некратным адресам будут возбуждать исключительную ситуацию

eip/ip (Instraction Pointer register) - регистр-указатель команд. Регистр eip/ip имеет разрядность 32/16 бит и содержит смещение следующей подлежащей выполнению команды относительно содержимого сегментного регистра cs в текущем сегменте команд. Этот регистр непосредственно недоступен программисту, но загрузка и изменение его значения производятся различными командами управления, к которым относятся команды условных и безусловных переходов, вызова процедур и возврата из процедур. Возникновение прерываний также приводит к модификации регистра eip/ip.

1.5 Системные регистры микропроцессора

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

Системные регистры можно разделить на три группы:

  •  четыре регистра управления;
  •  четыре регистра системных адресов;
  •  восемь регистров отладки.

1.6 Регистры управления

В группу регистров управления входят 4 регистра:
cr0, cr1, cr2, cr3.

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

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

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

  •  pe (Protect Enable), бит 0 — разрешение защищенного режима работы.
    Состояние этого флага показывает, в каком из двух режимов —
    реальном (pe=0) или защищенном (pe=1) — работает микропроцессор в данный момент времени.
  •  mp (Math Present), бит 1 — наличие сопроцессора. Всегда 1.
  •  ts (Task Switched), бит 3 — переключение задач.
    Процессор автоматически устанавливает этот бит при переключении на выполнение другой задачи.
  •  am (Aligment Mask), бит 18 — маска выравнивания.
    Этот бит разрешает (am = 1) или запрещает (am = 0) контроль выравнивания.
  •  cd (Cache Disable), бит 30, — запрещение кэш-памяти.
    С помощью этого бита можно запретить (cd = 1) или разрешить (cd = 0) использование внутренней кэш-памяти (кэш-памяти первого уровня).
  •  pg (PaGing), бит 31, — разрешение (pg = 1) или запрещение (pg = 0) страничного преобразования.
    Флаг используется при страничной модели организации памяти.

Регистр cr2 используется при страничной организации оперативной памяти для регистрации ситуации, когда текущая команда обратилась по адресу, содержащемуся в странице памяти, отсутствующей в данный момент времени в памяти.
В такой ситуации в микропроцессоре возникает исключительная ситуация с номером 14, и линейный 32-битный адрес команды, вызвавшей это исключение, записывается в регистр
cr2. Имея эту информацию, обработчик исключения 14 определяет нужную страницу, осуществляет ее подкачку в память и возобновляет нормальную работу программы;

Регистр cr3 также используется при страничной организации памяти.
Это так называемый
регистр каталога страниц первого уровня. Он содержит 20-битный физический базовый адрес каталога страниц текущей задачи. Этот каталог содержит 1024 32-битных дескриптора, каждый из которых содержит адрес таблицы страниц второго уровня. В свою очередь каждая из таблиц страниц второго уровня содержит 1024 32-битных дескриптора, адресующих страничные кадры в памяти. Размер страничного кадра - 4 Кбайт.

1.7 Регистры системных адресов

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

При работе в защищенном режиме микропроцессора адресное пространство делится на:

  •  глобальное — общее для всех задач;
  •  локальное — отдельное для каждой задачи.

Этим разделением и объясняется присутствие в архитектуре микропроцессора следующих системных регистров:

  •  регистра таблицы глобальных дескрипторов gdtr (Global Descriptor Table Register) имеющего размер 48 бит и содержащего 32-битовый (биты 16—47) базовый адрес глобальной дескрипторной таблицы GDT и 16-битовое (биты 0—15) значение предела, представляющее собой размер в байтах таблицы GDT;
  •  регистра таблицы локальных дескрипторов ldtr (Local Descriptor Table Register) имеющего размер 16 бит и содержащего так называемый селектор дескриптора локальной дескрипторной таблицы LDT. Этот селектор является указателем в таблице GDT, который и описывает сегмент, содержащий локальную дескрипторную таблицу LDT;
  •  регистра таблицы дескрипторов прерываний idtr (Interrupt Descriptor Table Register) имеющего размер 48 бит и содержащего 32-битовый (биты 16–47) базовый адрес дескрипторной таблицы прерываний IDT и 16-битовое (биты 0—15) значение предела, представляющее собой размер в байтах таблицы IDT;
  •  16-битового регистра задачи tr (Task Register), который подобно регистру ldtr, содержит селектор, то есть указатель на дескриптор в таблице GDT. Этот дескриптор описывает текущий сегмент состояния задачи (TSS — Task Segment Status). Этот сегмент создается для каждой задачи в системе, имеет жестко регламентированную структуру и содержит контекст (текущее состояние) задачи. Основное назначение сегментов TSS — сохранять текущее состояние задачи в момент переключения на другую задачу.

1.8 Регистры отладки

Это очень интересная группа регистров, предназначенных для аппаратной отладки. Средства аппаратной отладки впервые появились в микропроцессоре i486. Аппаратно микропроцессор содержит восемь регистров отладки, но реально из них используются только 6.

Регистры dr0, dr1, dr2, dr3 имеют разрядность 32 бит и предназначены для задания линейных адресов четырех точек прерывания. Используемый при этом механизм следующий: любой формируемый текущей программой адрес сравнивается с адресами в регистрах dr0...dr3, и при совпадении генерируется исключение отладки с номером 1.

Регистр dr6 называется регистром состояния отладки. Биты этого регистра устанавливаются в соответствии с причинами, которые вызвали возникновение последнего исключения с номером 1.

Перечислим эти биты и их назначение:

  •  b0 — если этот бит установлен в 1, то последнее исключение (прерывание) возникло в результате достижения контрольной точки, определенной в регистре dr0;
  •  b1 — аналогично b0, но для контрольной точки в регистре dr1;
  •  b2 — аналогично b0, но для контрольной точки в регистре dr2;
  •  b3 — аналогично b0, но для контрольной точки в регистре dr3;
  •  bd (бит 13) — служит для защиты регистров отладки;
  •  bs (бит 14) — устанавливается в 1, если исключение 1 было вызвано состоянием флага tf = 1 в регистре eflags;
  •  bt (бит 15) устанавливается в 1, если исключение 1 было вызвано переключением на задачу с установленным битом ловушки в TSS t = 1.

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

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

  •  место регистрации контрольной точки — только в текущей задаче или в любой задаче. Эти биты занимают младшие восемь бит регистра dr7 (по два бита на каждую контрольную точку (фактически точку прерывания), задаваемую регистрами dr0, dr1, dr2, dr3 соответственно).
    Первый бит из каждой пары — это так называемое локальное разрешение; его установка говорит о том, что точка прерывания действует если она находится в пределах адресного пространства текущей задачи.
    Второй бит в каждой паре определяет глобальное разрешение, которое говорит о том, что данная контрольная точка действует в пределах адресных пространств всех задач, находящихся в системе;
  •  тип доступа, по которому инициируется прерывание: только при выборке команды, при записи или при записи/чтении данных. Биты, определяющие подобную природу возникновения прерывания, локализуются в старшей части данного регистра.

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

  1.  Какие регистры называются пользовательскими, их назначение?
  2.  Перечислите регистры общего назначения.
  3.  Какие регистры относятся к сегментным регистрам?
  4.  Назначение регистра флагов.
  5.  Перечислите флаги состояния.
  6.  Какие регистры относятся к регистрам управления?
  7.  Перечислите регистры отладки, их назначение.

тема 2: Структура программы. Представление команд.

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

Предложения ассемблера бывают четырех типов:

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

2.1 Синтаксис ассемблера

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

а) Формат предложения ассемблера

б) Формат директив

в) Формат команд и макрокоманд

Рисунок 1-Синтаксис предложений

На этом рисунке:

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

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

Допустимыми символами при написании текста программ являются:

  1.  все латинские буквы: A—Z, a—z. При этом заглавные и строчные буквы считаются эквивалентными;
  2.  цифры от 0 до 9;
  3.  знаки ?, @, $, _, &;
  4.  разделители , . [ ] ( ) < > { } + / * % ! ' " ? \ = # ^.

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

Лексемами являются:

  •  идентификаторы — последовательности допустимых символов, использующиеся для обозначения таких объектов программы, как коды операций, имена переменных и названия меток. Правило записи идентификаторов заключается в следующем: идентификатор может состоять из одного или нескольких символов. В качестве символов можно использовать буквы латинского алфавита, цифры и некоторые специальные знаки — _, ?, $, @. Идентификатор не может начинаться символом цифры. Длина идентификатора может быть до 255 символов, хотя транслятор воспринимает лишь первые 32, а остальные игнорирует. Регулировать длину возможных идентификаторов можно с использованием опции командной строки mv. Кроме этого существует возможность указать транслятору на то, чтобы он различал прописные и строчные буквы либо игнорировал их различие (что и делается по умолчанию). Для этого применяются опции командной строки /mu, /ml, /mx;
  •  цепочки символов - последовательности символов, заключенные в одинарные или двойные кавычки;
  •  целые числа в одной из следующих систем счисления: двоичной, десятичной, шестнадцатеричной. Отождествление чисел при записи их в программах на ассемблере производится по определенным правилам:
    •  Десятичные числа не требуют для своего отождествления указания каких-либо дополнительных символов, например 25 или 139.
    •  Для отождествления в исходном тексте программы двоичных чисел необходимо после записи нулей и единиц, входящих в их состав, поставить латинское “b”, например 10010101b.
    •  Шестнадцатеричные числа имеют больше условностей при своей записи:
      •  Во-первых, они состоят из цифр 0...9, строчных и прописных букв латинского алфавита a, b, c, d, e, f или A, B, C, D, E, F.
      •  Во-вторых, у транслятора могут возникнуть трудности с распознаванием шестнадцатеричных чисел из-за того, что они могут состоять как из одних цифр 0...9 (например 190845), так и начинаться с буквы латинского алфавита (например ef15). Для того чтобы "объяснить" транслятору, что данная лексема не является десятичным числом или идентификатором, программист должен специальным образом выделять шестнадцатеричное число. Для этого на конце последовательности шестнадцатеричных цифр, составляющих шестнадцатеричное число, записывают латинскую букву “h”. Это обязательное условие. Если шестнадцатеричное число начинается с буквы, то перед ним записывается ведущий ноль: 0ef15h.

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

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

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

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

Рассмотрим подробнее характеристику операндов из приведенной классификации:

  •  Постоянные или непосредственные операнды — число, строка, имя или выражение, имеющие некоторое фиксированное значение. Имя не должно быть перемещаемым, то есть зависеть от адреса загрузки программы в память. К примеру, оно может быть определено операторами equ или =.

 

num     equ     5

imd = num-2

        mov     al,num  ;эквивалентно mov al,5 

;5 здесь непосредственный операнд

        add     [si],imd        ; imd=3 - непосредственный операнд

        mov     al,5            ;5 - непосредственный операнд

        

  •  В данном фрагменте определяются две константы, которые затем используются в качестве непосредственных операндов в командах пересылки mov и сложения add.  
  •  Адресные операнды — задают физическое расположение операнда в памяти с помощью указания двух составляющих адреса: сегмента и смещения (рисунке 4).

Рисунок  4- Синтаксис описания адресных операндов

К примеру:

 

        mov     ax,0000h

        mov     ds,ax

        mov     ax,ds:0000h     ;записать слово в ax из области памяти по

                                        ;физическому адресу 0000:0000

        

Здесь третья команда mov имеет адресный операнд.  

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

К примеру:

  

data    segment

mas_w   dw      25 dup (0)

code    segment

        lea     si,mas_w        ;mas_w - перемещаемый операнд

 

В этом фрагменте mas_w — символьное имя, значением которого является начальный адрес области памяти размером 25 слов. Полный физический адрес этой области памяти будет известен только после загрузки программы в память для выполнения.  

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

  

 jmp $+3 ;безусловный переход на команду mov

 cld ;длина команды cld составляет 1 байт

 mov al,1

  

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

   

 mov al,4 ;константу 4 заносим в регистр al

 mov dl,pass+4 ;байт по адресу pass+4 в регистр

dl

 add al,dl ;команда с регистровыми

операндами

  •  Базовый и индексный операнды. Этот тип операндов используется для реализации косвенной базовой, косвенной индексной адресации или их комбинаций и расширений 
  •  Структурные операнды используются для доступа к конкретному элементу сложного типа данных, называемого структурой 
  •  Записи (аналогично структурному типу) используются для доступа к битовому полю некоторой записи.

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

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

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

  •  Арифметические операторы 
  •  Операторы сдвига 
  •  Операторы сравнения 
  •  Логические операторы 
  •  Индексный оператор 
  •  Оператор переопределения типа 
  •  Оператор переопределения сегмента 
  •  Оператор именования типа структуры 
  •  Оператор получения сегментной составляющей адреса выражения 
  •  Оператор получения смещения выражения 
  •  Арифметические операторы. К ним относятся:
    •  унарные “+” и “”;
    •  бинарные “+” и “”;
    •  умножения “*”;
    •  целочисленного деления “/”;
    •  получения остатка от деления “mod”.

. Например,

    

tab_size equ 50 ;размер массива в байтах

size_el equ 2 ;размер элементов

;вычисляется число элементов массива и заносится в

регистр cx

 mov cx,tab_size / size_el ;оператор “/”

Рисунок 5- Синтаксис арифметических операций

Команда сложения (ADDition)

Схема команды: 

add приемник, источник 

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

Синтаксис
Алгоритм работы: 

  •  сложить операнды источник и приемник;
  •  записать результат сложения в приемник;
  •  установить флаги.

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

11

07

06

04

02

00

OF

SF

ZF

AF

PF

CF

r

r

r

r

r

Применение:
Команда add используется для сложения двух целочисленных операндов. Результат сложения помещается по адресу первого операнда. Если результат сложения выходит за границы операнда приемник (возникает переполнение), то учесть эту ситуацию следует путем анализа флага cf и последующего возможного применения команды adc. Например, сложим значения в регистре ax и области памяти ch. При сложении следует учесть возможность переполнения.

chiclo  dw      2015

rez     dd      0

...

        add     ax,chislo       ;(ax)=(ax)+ch

        mov     word ptr rez,ax

        jnc     dop_sum         ;переход, если результат не вышел за разрядную сетку

        adc     word ptr rez+2,0        ;расширить результат, для учета переноса

                                ;в старший разряд

dop_sum:

...

        

Деление целочисленное без знака и со знаком

DIV(Integer DIVide)

IDIV(Integer DIVide)

Схема команд: 

Схема команды: 

div делитель 

Назначение: выполнение операции деления двух двоичных беззнаковых значений.

Синтаксис
Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно и размер его зависит от размера делителя, который указывается в команде:

  •  если делитель размером в байт, то делимое должно быть расположено в регистре ax. После операции частное помещается в al, а остаток — в ah;
  •  если делитель размером в слово, то делимое должно быть расположено в паре регистров dx:ax, причем младшая часть делимого находится в ax. После операции частное помещается в ax, а остаток — в dx;
  •  если делитель размером в двойное слово, то делимое должно быть расположено в паре регистров edx:eax, причем младшая часть делимого находится в eax. После операции частное помещается в eax, а остаток — в edx.

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

11

07

06

04

02

00

OF

SF

ZF

AF

PF

CF

?

?

?

?

?

Применение:
Команда выполняет целочисленное деление операндов с выдачей результата деления в виде частного и остатка от деления. При выполнении операции деления возможно возникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает в одном из двух случаев: делитель равен 0 или частное слишком велико для его размещения в регистре eax/ax/al.

        mov     ax,10234

        mov     bl,154

        div     bl      ;ah=остаток, al=частное

        

Схема команды:   idiv делитель  

Назначение: операция деления двух двоичных значений со знаком.

Синтаксис
Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно, и размер его зависит от размера делителя, местонахождение которого указывается в команде:

  •  если делитель размером в байт, то делимое должно быть расположено в регистре ax. После операции частное помещается в al, а остаток — в ah;
  •  если делитель размером в слово, то делимое должно быть расположено в паре регистров dx:ax, причем младшая часть делимого находится в ax. После операции частное помещается в ax, а остаток — в dx;
  •  если делитель размером в двойное слово, то делимое должно быть расположено в паре регистров edx:eax, причем младшая часть делимого находится в eax. После операции частное помещается в eax, а остаток — в edx;

Остаток всегда имеет знак делимого. Знак частного зависит от состояния знаковых битов (старших разрядов) делимого и делителя.
Состояние флагов после выполнения команды: 

11

07

06

04

02

00

OF

SF

ZF

AF

PF

CF

?

?

?

?

?

Применение:
Команда выполняет целочисленное деление операндов с учетом их знаковых разрядов. Результатом деления являются частное и остаток от деления. При выполнении операции деления возможно возникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает в одном из двух случаев: делитель равен 0 или частное слишком велико для его размещения в регистре eax/ax/al.

;деление слов

        mov     ax,1045 ;делимое

        mov     bx,587  ;делитель

cwd             ;расширение делимого dx:ax

        idiv    bx      ;частное в ax, остаток в dx

        

Умножение целочисленное без знака и со знаком

MUL(Integer MULtiply)

IMUL(Integer MULtiply)

Схема команд: 

mul множитель_1 

imul множ_1

Назначение: операция умножения двух целочисленных двоичных значений со знаком.

Синтаксис 
Алгоритм работы:

Алгоритм работы команды зависит от используемой формы команды. Форма команды с одним операндом требует явного указания местоположения только одного сомножителя, который может быть расположен в ячейке памяти или регистре. Местоположение второго сомножителя фиксировано и зависит от размера первого сомножителя:

  •  если операнд, указанный в команде, — байт, то второй сомножитель располагается в al;
  •  если операнд, указанный в команде, — слово, то второй сомножитель располагается в ax;
  •  если операнд, указанный в команде, — двойное слово, то второй сомножитель располагается в eax.

Результат умножения для команды с одним операндом также помещается в строго определенное место, определяемое размером сомножителей:

  •  при умножении байтов результат помещается в ax;
  •  при умножении слов результат помещается в пару dx:ax;
  •  при умножении двойных слов результат помещается в пару edx:eax.

Команды с двумя и тремя операндами однозначно определяют расположение результата и сомножителей следующим образом:

  •  в команде с двумя операндами первый операнд определяет местоположение первого сомножителя. На его место впоследствии будет записан результат. Второй операнд определяет местоположение второго сомножителя;
  •  в команде с тремя операндами первый операнд определяет местоположение результата, второй операнд — местоположение первого сомножителя, третий операнд может быть непосредственно заданным значением размером в байт, слово или двойное слово.

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

11

07

06

04

02

00

OF

SF

ZF

AF

PF

CF

r

?

?

?

r

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

  •  для однооперандной формы команды imul регистры ax/dx/edx являются знаковыми расширениями регистров al/ax/eax;
  •  для двухоперандной формы команды imul для размещения результата умножения достаточно размерности указанных регистров назначения r16/r32;
  •  то же для трехоперандной команды умножения.

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

.486

...

        mov     bx,186

        imul    eax,bx,8

;если результату не хватило размерности операнда1,

;то перейдем на m1, где скорректируем ситуацию:

        jc      m1

        

Команда обмена  XCHG (eXCHanGe)

Схема команды: 

xchg операнд_1,операнд_2 

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

Синтаксис
Алгоритм работы:
обмен содержимого операнд_1 и операнд_2.

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

выполнение команды не влияет на флаги

Применение:
Команду xchg можно использовать для выполнения операции обмена двух операндов с целью изменения порядка следования байт, слов, двойных слов или их временного сохранения в регистре или памяти. Альтернативой является использование для этой цели стека.

;поменять порядок следования байт в слове

ch1     label   byte

        dw      0f85ch

...

        mov     al,ch1

        xchg    ch1+1,al

        mov     ch1,al

        

тема 3: ПЕРЕХОДЫ. Логические команды.

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

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

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

1.Логические данные

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

Исчисление высказываний очень гармонично сочетается с принципами работы компьютера и основными методами его программирования. Все аппаратные компоненты компьютера построены на логических микросхемах. Система представления информации в компьютере на самом нижнем уровне основана на понятии бита. Бит, имея всего два состояния: 0 (ложно) и 1 (истинно), — естественным образом вписывается в исчисление высказываний.

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

  •  отрицание (логическое НЕ); 
  •  логическое сложение (логическое включающее ИЛИ); 
  •  логическое умножение (логическое И); 
  •  логическое исключающее сложение (логическое исключающее ИЛИ). 

отрицание (логическое НЕ) — логическая операция над одним операндом, результатом которой является величина, обратная значению исходного операнда.
Эта операция однозначно характеризуется следующей таблицей истинности (табл. 1).

Таблица 1. Таблица истинности для логического отрицания

Значение операнда

0

1

Результат операции

1

0

логическое сложение (логическое включающее ИЛИ) — логическая операция над двумя операндами, результатом которой является “истина” (1), если один или оба операнда имеют значение “истина” (1), и “ложь” (0) — если оба операнда имеют значение “ложь” (0).
Эта операция описывается с помощью следующей таблицы истинности (табл. 2).

Таблица 2. Таблица истинности для логического включающего ИЛИ

Значение операнда 1

0

0

1

1

Значение операнда 2

0

1

0

1

Результат операции

0

1

1

1

логическое умножение (логическое И) — логическая операция над двумя операндами, результатом которой является “истина” (1) только в том случае, если оба операнда имеют значение “истина” (1). Во всех остальных случаях значение операции “ложь” (0).
Эта операция описывается с помощью следующей таблицы истинности (табл.3).

Таблица 3. Таблица истинности для логического И

Значение операнда 1

0

0

1

1

Значение операнда 2

0

1

0

1

Результат операции

0

0

0

1

логическое исключающее сложение (логическое исключающее ИЛИ) — логическая операция над двумя операндами, результатом которой является “истина” (1), если только один из двух операндов имеет значение “истина” (1), и ложь (0), если оба операнда имеют значение “ложь” (0) или “истина” (1).
Эта операция описывается с помощью следующей таблицы истинности(табл. 4).

Таблица 4. Таблица истинности для логического исключающего ИЛИ

Значение операнда 1

0

0

1

1

Значение операнда 2

0

1

0

1

Результат операции

0

1

1

0

 

Система команд микропроцессора содержит пять команд, поддерживающих данные операции. Эти команды выполняют логические операции над битами операндов. Размерность операндов, естественно, должна быть одинакова. Например, если размерность операндов равна слову (16 бит), то логическая операция выполняется сначала над нулевыми битами операндов и ее результат записывается на место бита 0 результата. Далее команда последовательно повторяет эти действия над всеми битами с первого до пятнадцатого. Возможные варианты размерности операндов для каждой команды приведены в “Справочнике команд”.  

2. Логические команды

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

and операнд_1,операнд_2 — операция логического умножения.
Команда выполняет поразрядно логическую операцию И (конъюнкцию) над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

or операнд_1,операнд_2 — операция логического сложения.
Команда выполняет поразрядно логическую операцию ИЛИ (дизъюнкцию) над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

xor операнд_1,операнд_2 — операция логического исключающего сложения.
Команда выполняет поразрядно логическую операцию исключающего ИЛИ над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

test операнд_1,операнд_2 — операция “проверить” (способом логического умножения).
Команда выполняет поразрядно логическую операцию И над битами операндов операнд_1 и операнд_2. Состояние операндов остается прежним, изменяются только флаги zf, sf, и pf, что дает возможность анализировать состояние отдельных битов операнда без изменения их состояния.

not операнд — операция логического отрицания.
Команда выполняет поразрядное инвертирование (замену значения на обратное) каждого бита операнда. Результат записывается на место операнда.

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

Предыдущее обсуждение выявило некоторые детали механизма перехода. Команды перехода модифицируют регистр указателя команды eip/ip и, возможно, сегментный регистр кода cs. Что именно должно подвергнуться модификации, зависит:

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

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

  •  near ptr — прямой переход на метку внутри текущего сегмента кода. Модифицируется только регистр eip/ip (в зависимости от заданного типа сегмента кода use16 или use32) на основе указанного в команде адреса (метки) или выражения, использующего символ извлечения значения СчА — $;
  •  far ptr — прямой переход на метку в другом сегменте кода. Адрес перехода задается в виде непосредственного операнда или адреса (метки) и состоит из 16-битного селектора и 16/32-битного смещения, которые загружаются, соответственно, в регистры cs и ip/eip;
  •  word ptr — косвенный переход на метку внутри текущего сегмента кода. Модифицируется (значением смещения из памяти по указанному в команде адресу, или из регистра) только eip/ip. Размер смещения 16 или 32 бит;
  •  dword ptr — косвенный переход на метку в другом сегменте кода. Модифицируются (значением из памяти — и только из памяти, из регистра нельзя) оба регистра, cs и eip/ip. Первое слово/двойное слово этого адреса представляет смещение и загружается в ip/eip; второе/третье слово загружается в cs.

3.1 Команда безусловного перехода jmp

Синтаксис команды безусловного перехода
jmp [модификатор] адрес_перехода - безусловный переход без сохранения информации о точке возврата.

Адрес_перехода представляет собой адрес в виде метки либо адрес области памяти, в которой находится указатель перехода.

Всего в системе команд микропроцессора есть несколько кодов машинных команд безусловного перехода jmp.
Их различия определяются дальностью перехода и способом задания целевого адреса.
Дальность перехода определяется местоположением операнда адрес_перехода. Этот адрес может находиться в текущем сегменте кода или в некотором другом сегменте. В первом случае переход называется внутрисегментным, или близким, во втором — межсегментным, или дальним.
Внутрисегментный переход предполагает, что изменяется только содержимое регистра
eip/ip.
Можно выделить три варианта внутрисегментного использования команды jmp:

  •  прямой короткий;
  •  прямой;
  •  косвенный.

4. Условные переходы
Микропроцессор имеет 18 команд условного перехода (см. “Описание команд”). Эти команды позволяют проверить:

  •  отношение между операндами со знаком (“больше — меньше”);
  •  отношение между операндами без знака (“выше — ниже”)2;
  •  состояния арифметических флагов zf, sf, cf, of, pf (но не af).

Команды условного перехода имеют одинаковый синтаксис:
jcc метка_перехода 

Как видно, мнемокод всех команд начинается с “j” — от слова jump (прыжок), cc — определяет конкретное условие, анализируемое командой.
Что касается операнда
метка_перехода, то эта метка может находится только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается. В связи с этим отпадает вопрос о модификаторе, который присутствовал в синтаксисе команд безусловного перехода. В ранних моделях микропроцессора (i8086, i80186 и i80286) команды условного перехода могли осуществлять только короткие переходы — на расстояние от –128 до +127 байт от команды, следующей за командой условного перехода. Начиная с модели микропроцессора 80386 это ограничение снято, но, как видите, только в пределах текущего сегмента кода.

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

  •  любая команда, изменяющая состояние арифметических флагов;
  •  команда сравнения cmp, сравнивающая значения двух операндов;
  •  состояние регистра ecx/cx.

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

4.1 Команда сравнения cmp

Команда сравнения cmp имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания.
sub операнд_1,операнд_2. Команда cmp так же, как и команда sub, выполняет вычитание операндов и устанавливает флаги. Единственное, чего она не делает — это запись результата вычитания на место первого операнда.

Синтаксис команды cmp:
cmp операнд_1,операнд_2 (compare) — сравнивает два операнда и по результатам сравнения устанавливает флаги.

Флаги, устанавливаемые командой cmp, можно анализировать специальными командами условного перехода. Прежде чем мы их рассмотрим, уделим немного внимания мнемонике этих команд условного перехода (табл. 1). Понимание обозначений при формировании названия команд условного перехода (элемент в названии команды jcc, обозначенный нами cc) облегчит их запоминание и дальнейшее практическое использование.

Таблица 1. Значение аббревиатур в названии команды jcc

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

Английский

Русский

Тип операндов

E e

equal

Равно

Любые

N n

not

Не

Любые

G g

greater

Больше

Числа со знаком

L l

less

Меньше

Числа со знаком

A a

above

Выше, в смысле “больше”

Числа без знака

B b

below

Ниже, в смысле “меньше”

Числа без знака

Таблица 2. Перечень команд условного перехода для команды cmp операнд_1,операнд_2 

Типы операндов

Мнемокод команды условного перехода

Критерий условного перехода

Значения флагов для осществления перехода

Любые 

je 

операнд_1 = операнд_2 

zf = 1 

Любые 

jne 

операнд_1<>операнд_2 

zf = 0 

Со знаком 

jl/jnge 

операнд_1 < операнд_2 

sf <> of

Со знаком 

jle/jng 

операнд_1 <= операнд_2 

sf <> of or zf = 1 

Со знаком 

jg/jnle 

операнд_1 > операнд_2 

sf = of and zf = 0

Со знаком 

jge/jnl 

операнд_1 => операнд_2 

sf = of 

Без знака 

jb/jnae 

операнд_1 < операнд_2 

cf = 1 

Без знака 

jbe/jna 

операнд_1 <= операнд_2 

cf = 1 or zf=1 

Без знака 

ja/jnbe 

операнд_1 > операнд_2 

cf = 0 and zf = 0 

Без знака 

jae/jnb 

операнд_1 => операнд_2 

cf = 0 

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

тема 4:Организация циклов.

Цикл, как известно, представляет собой важную алгоритмическую структуру, без использования которой не обходится, наверное, ни одна программа.
Организовать циклическое выполнение некоторого участка программы можно, к примеру, используя команды условной передачи управления или команду безусловного перехода jmp. При такой организации цикла все операции по его организации выполняются “вручную”. Но, учитывая важность такого алгоритмического элемента, как цикл, разработчики микропроцессора ввели в систему команд группу из трех команд, облегчающую программирование циклов. Эти команды также используют регистр
ecx/cx как счетчик цикла.
loop метка_перехода (Loop) — повторить цикл. Команда позволяет организовать циклы, подобные циклам for в языках высокого уровня с автоматическим уменьшением счетчика цикла. Работа команды заключается в выполнении следующих действий:

  •  декремента регистра ecx/cx;
  •  сравнения регистра ecx/cx с нулем:
    •  если (ecx/cx) > 0, то управление передается на метку перехода;
    •  если (ecx/cx) = 0, то управление передается на следующую после loop команду.

Пример: Вычислить Y=∑ (i + П (j+b) )   при  b=3

Программа будет иметь вид:

MASM

MODEL small

STACK 256

.data

B db 3

I  db 1

J db ?

.code

.startup

jmp main

include io.inc

main:

MOV CX,3

MOV  BH, 0 ; начальное значение суммы

M2: MOV SI,CX ; спасаем значение счетчика внешнего цикла

MOV CX,2

MOV AL,1 ; начальное значение произведения

MOV J,1

M1: MOV BL, J

ADD BL, B

MUL BL

INC J       ; увеличиваем значение J на единицу

LOOP M1

ADD BH, I

ADD BH, AL

INC I       ; увеличиваем значение I на единицу

MOV CX, SI ; восстанавливаем значение счетчика внешнего цикла

LOOP M2

MOV AL, BH

MOV DH, 0

MOV DL, 5

CALL PROCOUTNUM

.exit

end


loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0.
Команды loope и loopz — абсолютные синонимы, поэтому используйте ту команду, которая вам больше нравиться. Работа команд заключается в выполнении следующих действий:

  •  декремента регистра ecx/cx;
  •  сравнения регистра ecx/cx с нулем;
  •  анализа состояния флага нуля zf:
    •  если (ecx/cx) > 0 и zf = 1, управление передается на метку перехода;
    •  если (ecx/cx) = 0 или zf = 0, управление передается на следующую после loop команду.

loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1.
Команды loopne и loopnz также абсолютные синонимы. Работа команд заключается в выполнении следующих действий:

  •  декремента регистра ecx/cx;
  •  сравнения регистра ecx/cx с нулем;
  •  анализа состояния флага нуля zf:
    •  если (ecx/cx) > 0 и zf = 0, управление передается на метку перехода;
    •  если (ecx/cx)=0 или zf=1, управление передается на следующую после loop команду.

Команды loope/loopz и loopne/loopnz по принципу своей работы являются взаимообратными. Они расширяют действие команды loop тем, что дополнительно анализируют флаг zf, что дает возможность организовать досрочный выход из цикла, используя этот флаг в качестве индикатора.

Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт). Для работы с длинными циклами придется использовать команды условного перехода и команду jmp, поэтому постарайтесь освоить оба способа организации циклов. 

тема 5: Подпрограммы.

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

Для описания последовательности команд в виде процедуры в языке ассемблера используются две директивы: PROC и ENDP.

Синтаксис описания процедуры таков (рисунок 1).

Рисунок 1 -Синтаксис описания процедуры в программе

Из рисунка 1 видно, что в заголовке процедуры (директиве PROC) обязательным является только задание имени процедуры. Среди большого количества операндов директивы PROC следует особо выделить [расстояние].
Этот атрибут может принимать значения
near или far и характеризует возможность обращения к процедуре из другого сегмента кода. По умолчанию атрибут [расстояние] принимает значение near.

Процедура может размещаться в любом месте программы, но так, чтобы на нее случайным образом не попало управление. Если процедуру просто вставить в общий поток команд, то микропроцессор будет воспринимать команды процедуры как часть этого потока и соответственно будет осуществлять выполнение команд процедуры.
Более подробно вопросы, связанные с описанием и использованием процедур в программах ассемблера, рассматриваются на уроках 10 и 14. Примеры использования процедур вы можете посмотреть в приложении 7. 
 

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

 

Схема команды: 

call <имя процедуры> 

Назначение: 

  •  передача управления близкой или дальней процедуре с запоминанием в стеке адреса точки возврата;
  •  переключение задач.

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

  •  метка ближняя — в стек заносится содержимое указателя команд eip/ip и в этот же регистр загружается новое значение адреса, соответствующее метке;
  •  метка дальняя — в стек заносится содержимое указателя команд eip/ip и cs. Затем в эти же регистры загружаются новые значения адресов, соответствующие дальней метке;
  •  r16, 32 или m16, 32 — определяют регистр или ячейку памяти, содержащие смещения в текущем сегменте команд, куда передается управление. При передаче управления в стек заносится содержимое указателя команд eip/ip;
  •  указатель на память — определяет ячейку памяти, содержащую 4 или 6-байтный указатель на вызываемую процедуру. Структура такого указателя 2+2 или 2+4 байта. Интерпретация такого указателя зависит от режима работы микропроцессора:
  •  в реальном режиме — в зависимости от размера адреса (use16 или use32) первые два байта трактуются как сегментный адрес, вторые два/четыре байта, как смещение целевой метки передачи управления. В стеке запоминается содержимое регистров cs и eip/ip;
  •  в защищенном режиме — интерпретация цели передачи управления зависит от значения байта AR дескриптора, определяемого селекторной частью указателя. Целью здесь являются дальний вызов процедуры без изменения уровня привилегий, дальний вызов процедуры с изменением уровня привилегий или переключение задачи.

тема 6: Команды сдвига.

Все команды сдвига перемещают биты в поле операнда влево или вправо в зависимости от кода операции. Все команды сдвига имеют одинаковую структуру:

коп операнд, счетчик_сдвигов 

Количество сдвигаемых разрядов — счетчик_сдвигов — располагается, как видите, на месте второго операнда и может задаваться двумя способами:

  •  статически, что предполагает задание фиксированного значения с помощью непосредственного операнда;
  •  динамически, что означает занесение значения счетчика сдвигов в регистр cl перед выполнением команды сдвига.

Исходя из размерности регистра cl, понятно, что значение счетчика сдвигов может лежать в диапазоне от 0 до 255. Но на самом деле это не совсем так.
В целях оптимизации микропроцессор воспринимает только значение
пяти младших битов счетчика, то есть значение лежит в диапазоне от 0 до 31.
В последних моделях микропроцессора, в том числе и в микропроцессоре Pentium, есть дополнительные команды, позволяющие делать 64-разрядные сдвиги. Мы их рассмотрим чуть позже.

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

По принципу действия команды сдвига можно разделить на два типа:

  •  команды линейного сдвига; 
  •  команды циклического сдвига. 

1. Команды линейного сдвига

К командам этого типа относятся команды, осуществляющие сдвиг по следующему алгоритму:

  •  очередной “выдвигаемый” бит устанавливает флаг cf;
  •  бит, вводимый в операнд с другого конца, имеет значение 0;
  •  при сдвиге очередного бита он переходит во флаг cf, при этом значение предыдущего сдвинутого бита теряется! 

Команды линейного сдвига делятся на два подтипа:

  •  команды логического линейного сдвига;
  •  команды арифметического линейного сдвига.

К командам логического линейного сдвига относятся следующие:

shl операнд,счетчик_сдвигов (Shift Logical Left) - логический сдвиг влево.
Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули;

shr операнд,счетчик_сдвигов (Shift Logical Right) — логический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество битов, определяемое значением счетчик_сдвигов. Слева (в позицию старшего, знакового бита) вписываются нули. На рисунке 1 показан принцип работы этих команд.

Рисунок 1- Схема работы команд линейного логического сдвига

Ниже показан фрагмент программы, который выполняет преобразование двух неупакованных BCD-чисел в слове памяти bcd_dig в упакованное BCD-число в регистре al.

 

        ...

bcd_dig dw      0905h   ;описание неупакованного BCD-числа 95

...

        mov     ax,bcd_dig      ;пересылка

        shl     ah,4    ;сдвиг влево

        add     al,ah   ;сложение для получения результата: al=95h

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

sal операнд,счетчик_сдвигов (Shift Arithmetic Left) — арифметический сдвиг влево.
Содержимое операнда сдвигается влево на количество битов, определяемое значением
счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули. Команда sal не сохраняет знака, но устанавливает флаг cf в случае смены знака очередным выдвигаемым битом. В остальном команда sal полностью аналогична команде shl;

sar операнд,счетчик_сдвигов (Shift Arithmetic Right) — арифметический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество битов, определяемое значением
счетчик_сдвигов. Слева в операнд вписываются нули. Команда sar сохраняет знак, восстанавливая его после сдвига каждого очередного бита.
На рисунке 2 показан принцип работы команд линейного арифметического сдвига.

Рисунок 2 -Схема работы команд линейного арифметического сдвига 

2. Команды циклического сдвига

К командам циклического сдвига относятся команды, сохраняющие значения сдвигаемых бит. Есть два типа команд циклического сдвига:

  •  команды простого циклического сдвига;
  •  команды циклического сдвига через флаг переноса cf.

К командам простого циклического сдвига относятся:

rol операнд,счетчик_сдвигов (Rotate Left) — циклический сдвиг влево.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом
счетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа.

ror операнд,счетчик_сдвигов (Rotate Right) — циклический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом
счетчик_сдвигов. Сдвигаемые вправо биты записываются в тот же операнд слева.

Рисунок 3- Схема работы команд простого циклического сдвига

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

 

        ...

        mov     eax,ffff0000h

        mov     cl,16

        rol     eax,cl

Команды циклического сдвига через флаг переноса cf отличаются от команд простого циклического сдвига тем, что сдвигаемый бит не сразу попадает в операнд с другого его конца, а записывается сначала в флаг переноса cf. Лишь следующее исполнение данной команды сдвига (при условии, что она выполняется в цикле) приводит к помещению выдвинутого ранее бита с другого конца операнда (рисунке 4).

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

rcl операнд,счетчик_сдвигов (Rotate through Carry Left) — циклический сдвиг влево через перенос.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом
счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.

rcr операнд,счетчик_сдвигов (Rotate through Carry Right) — циклический сдвиг вправо через перенос.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом
счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.

Рисунок 4 -Команды циклического сдвига через флаг переноса cf

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

3. Дополнительные команды сдвига

Система команд последних моделей микропроцессоров Intel, начиная с i80386, содержит дополнительные команды сдвига, расширяющие возможности, рассмотренные нами ранее.
Это — команды сдвигов
двойной точности:

shld операнд_1,операнд_2,счетчик_сдвигов — сдвиг влево двойной точности.
Команда shld производит замену путем сдвига битов операнда операнд_1 влево, заполняя его биты справа значениями битов, вытесняемых из операнд_2 согласно схеме на рисунке 5. Количество сдвигаемых бит определяется значением
счетчик_сдвигов, которое может лежать в диапазоне 0...31. Это значение может задаваться непосредственным операндом или содержаться в регистре cl. Значение операнд_2 не изменяется.

Рисунок 5 -Схема работы команды shld

shrd 

операнд_1,операнд_2,счетчик_сдвигов — сдвиг вправо двойной точности.
Команда производит замену путем сдвига битов операнда операнд_1 вправо, заполняя его биты слева значениями битов, вытесняемых из операнд_2 согласно схеме на рисунке 6. Количество сдвигаемых бит определяется значением
счетчик_сдвигов, которое может лежать в диапазоне 0...31. Это значение может задаваться непосредственным операндом или содержаться в регистре cl. Значение операнд_2 не изменяется.

Рисунок 6- Схема работы команды shrd

Как мы отметили, команды shld и shrd осуществляют сдвиги до 32 разрядов, но за счет особенностей задания операндов и алгоритма работы эти команды можно использовать для работы с полями длиной до 64 бит.
Например, рассмотрим, как можно осуществить сдвиг влево на 16 бит поля из 64 бит.

 

;...

.data

pole_l  dd      0b21187f5h1

pole_h  dd      45ff6711h

.code

;...

.386

        mov     cl,16   ;загрузка счетчика сдвига в cl

        mov     eax,pole_h

        shld    pole_l,eax,cl

        shl     pole_h,cl       ;pole_l=87f50000h, pole_h=6711b211h

Литература.

Основная:

  1.  Пильщиков В.Н. Assembler. Программирование на языке ассемблер IBM PC-М: Диалог-Мифи.-2003
  2.  Юров В., Хорошенко С. Assembler: учебный курс.-СПб: Питер Ком, 1999.-672 с.:ил.
  3.  Абель П. Язык Assemblerа для IBM PC и программирования: Пер. с англ.-М.: Высшая школа, 1992.-477 с.
  4.  Нортон П., Сохуэ Д. Язык Assemblerа для IBM PC: Пер. с англ.-М.: Финансы и статистика, 1992.-352 с.
  5.  Скенлон Л. Персональные ЭВМ IBM PC и XT. Программирование на языке Assemblerа: Пер. с англ.-М.: Радио и связь, 1991. 336 с.

Дополнительная:

  1.  Электронные вычислительные машины в 8-ми книгах. Уч. пособие для Вузов/под ред. Савельева А.Я.
  2.  Брябрин В.М.  Программное обеспечение персональных ЭВМ. – М.: «Наука» -1998.


 

А также другие работы, которые могут Вас заинтересовать

72588. Обязательность исполнения решений и предписаний антимонопольного органа 12.5 KB
  Должностные лица антимонопольного органа наделены полномочием привлекать к административной ответственности лиц совершивших соответствующие правонарушения. Адресатами данной обязанности являются: коммерческие организации их должностные лица; некоммерческие организации их должностные лица...
72589. Ответственность за нарушение антимонопольного законодательства и законодательства о монополиях 14.71 KB
  Ответственность за нарушение антимонопольного законодательства является сравнительно молодым российским правовым институтом и представляет собой симбиоз норм и принципов из различных отраслей права цель которых обеспечить должный правовой режим экономической конкуренции.
72590. Принудительное разделение или выделение коммерческих организаций, а также некоммерческих организаций, осуществляющих деятельность, приносящую им доход 13.12 KB
  В случае систематического осуществления монополистической деятельности занимающей доминирующее положение коммерческой организацией а также некоммерческой организацией осуществляющей деятельность приносящую ей доход суд по иску антимонопольного органа в отношении кредитной...
72591. Основания для возбуждения дела о нарушении антимонопольного законодательства, место рассмотрения дела, а также последствия выявления признаков административного правонарушения при рассмотрении дела о нарушении антимонопольного законодательства 13.13 KB
  Антимонопольный орган в пределах своих полномочий возбуждает и рассматривает дела о нарушении антимонопольного законодательства принимает по результатам их рассмотрения решения и выдает предписания. Основанием для возбуждения и рассмотрения антимонопольным органом дела о нарушении...
72592. Порядок обжалования решений и предписаний антимонопольного органа 11.84 KB
  Согласно ст. 52 Закона о защите конкуренции решение и (или) предписание антимонопольного органа может быть обжаловано в течение трех месяцев со дня принятия решения или предписания. Как правило, заявления об оспаривании актов антимонопольного органа подаются в арбитражный...
72593. Лица, участвующие в деле о нарушении антимонопольного законодательства. Права лиц, участвующих в деле о нарушении антимонопольного законодательства 14 KB
  Лицами участвующими в деле о нарушении антимонопольного законодательства являются: 1 заявитель лицо подавшее заявление государственный орган орган местного самоуправления направившие материалы; 2 ответчик по делу лицо в отношении которого подано заявление направлены материалы или в действиях...
72594. Рассмотрение дела о нарушении антимонопольного законодательства. Предписание по делу о нарушении антимонопольного законодательства 13.59 KB
  Статья 45 Закона о защите конкуренции регулирует порядок рассмотрения комиссией дела о нарушении антимонопольного законодательства. В процессе рассмотрения дела заслушиваются мнения и пояснения лиц участвующих в деле исследуются доказательства заслушиваются лица располагающие данными...
72595. Понятие и структура рынка. Субъектный состав рынка, его границы 69.17 KB
  Если потребитель готов заменить одну продукцию на другую кардинально отличающуюся от нее по характеристикам например молоко на чай то эти виды продукции составляют группу взаимозаменяемых товаров и определяют так называемые продуктовые границы рынка.
72596. Доминирующее положение на товарном рынке: порядок выявления, определения и доказывания. Качественные и количественные критерии доминирования 16.28 KB
  Доминирующим положением признается положение хозяйствующего субъекта группы лиц или нескольких хозяйствующих субъектов групп лиц на рынке определенного товара дающее такому хозяйствующему субъекту группе лиц или таким хозяйствующим субъектам группам лиц возможность оказывать решающее...