Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ASM.docx
Скачиваний:
3
Добавлен:
31.07.2019
Размер:
616.28 Кб
Скачать

Il указателей на ячейки памяти.

В принципе, все эти регистры доступны для хранения операндов без особых

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

функциональное назначение, закрепленное на уровне логики работы машинных

команд. Среди всех этих регистров особо следует выделить регистр ESP. Его не сле-

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

в нем хранится указатель на вершину стека программы.

Все регистры этой группы позволяют обращаться к своим «младшим» частям

(см. рис. 2.5). Обращение производится по их именам. Важно отметить, что исполь-

зовать для самостоятельной адресации можно только младшие 16- и 8-разрядные

части этих регистров. Старшие 16 битов как самостоятельные объекты недоступны.

Это сделано, как мы отметили ранее, для совместимости с первыми 16-разрядны-

ми моделями процессоров фирмы Intel. Перечислим регистры, относящиеся к груп-

пе регистров общего назначения и физически находящиеся в процессоре внутри

арифметико-логического устройства (поэтому их еще называют регистрами АЛУ):

к регистр-аккумулятор (Accumulator register) EAX/AX/AH/AL применяется для

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

обязательно;

т базовый регистр (Base register) EBX/BX/BH/BL применяется для хранения базо-

вого адреса некоторого объекта в памяти;

II регистр-счетчик (Count register) ecx/cx/ch/cl применяется в командах, произ-

водящих некоторые повторяющиеся действия. Использование регистра-счет-

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

команда организации цикла LOOP помимо передачи управления анализирует

и уменьшает на единицу значение регистра ЕСХ/СХ;

т регистр данных (Data register) EDX/DX/DH/DL, так же как и регистр ЕАХ/АХ/АН/

AL, хранит промежуточные данные (в некоторых командах его явное использо-

вание обязательно, в других он используется неявно).

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

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

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

И регистр индекса источника (Source Index register) ESI/SI в цепочечных опера-

циях содержит текущий адрес элемента в цепочке-источнике;

il регистр индекса приемника (Destination Index register) EDI/DI в цепочечных

операциях содержит текущий адрес в цепочке-приемнике.

В архитектуре процессора на программно-аппаратном уровне поддерживается

такая структура данных, как стек. Для работы со стеком в системе команд процес-

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

существуют специальные регистры:

;»; регистр указателя стека (Stack Pointer register) ESP/SP содержит указатель на

вершину стека в текущем сегменте стека;

II регистр указателя базы кадра стека (Base Pointer register) EBP/BP предназна-

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

Не стоит пугаться столь жесткого функционального назначения регистров АЛ У.

На самом деле при программировании хранить операнды команд можно в боль-

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

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

Цель подобного жесткого закрепления регистров для этих команд — более ком-

пактная кодировка их машинного представления. Знание особенностей исполь-

зования регистров машинными командами (см. приложение) позволяет, при

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

тивно программировать алгоритм.

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

Процессоры Intel аппаратно поддерживают сегментную организацию программы.

Это означает, что любая программа состоит из трех сегментов: кода, данных и сте-

ка. Логически машинные команды в архитектуре IA-32 построены так, что при

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

используется информация из вполне определенных сегментных регистров. В за-

висимости от режима работы процессора по их содержимому определяются адре-

са памяти, с которых начинаются соответствующие сегменты. В программной мо-

дели IA-32 имеется шесть сегментных регистров CS, SS, DS, ES, GS, FS, служащих для

доступа к четырем типам сегментов.

ii Сегмент кода содержит команды программы. Для доступа к этому сегменту слу-

жит регистр сегмента кода (Code Segment register) CS. Он содержит адрес сег-

мента с машинными командами, к которому имеет доступ процессор (эти ко-

манды загружаются в конвейер процессора).

ii Сегмент данных содержит обрабатываемые программой данные. Для доступа

к этому сегменту служит регистр сегмента данных (Data Segment register) DS,

который хранит адрес сегмента данных текущей программы.

ш Сегмент стека представляет собой область памяти, называемую стеком. Рабо-

ту со стеком процессор организует по следующему принципу: последний запи-

санный в эту область элемент выбирается первым. Для доступа к этой области

служит регистр сегмента стека (Stack Segment register) SS, содержащий адрес

сегмента стека.

№ Дополнительный сегмент данных. Неявно алгоритмы выполнения большинства

машинных команд предполагают, что обрабатываемые ими данные расположе-

ны в сегменте данных, адрес которого находится в регистре сегмента данных DS.

Если программе недостаточно одного сегмента данных, то она имеет возмож-

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

от основного сегмента данных, адрес которого содержится в регистре DS, при

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

вать явно с помощью специальных префиксов переопределения сегментов в ко-

манде. Адреса дополнительных сегментов данных должны содержаться в реги-

страх дополнительного сегмента данных (Extension Data Segment registers) ES,

GS, FS.

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

В процессор включены два регистра (см. рис. 2.5), постоянно содержащие инфор-

мацию о состоянии как самого процессора, так и программы, команды которой он

в данный момент обрабатывает:

ii регистр-указатель команд EIP/IP;

it регистр флагов Е FLAGS/FLAGS.

С помощью этих регистров можно также ограниченным образом управлять со-

стоянием процессора.

Регистр-указатель команд (Instruction Pointer register) EIP/IP имеет разрядность

32(16) бита и содержит смещение следующей подлежащей выполнению команды

относительно содержимого регистра сегмента кода CS в текущем сегменте команд.

Этот регистр непосредственно недоступен программисту, но загрузка и изменение

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

сятся команды условных и безусловных переходов, вызова процедур и возврата из

процедур. Возникновение прерываний также приводит к модификации регистра

EIP/IP.

Разрядность регистра флагов (flag register) EFLAGS/FLAGS равна 32(16) битам. От-

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

и называются флагами. Младшая часть регистра EFLAGS/FLAGS полностью анало-

гична регистру FLAGS процессора i8086. На рис. 2.6 показано содержимое регистра

EFLAGS.

Исходя из особенностей использования, флаги регистра EFLAGS/FLAGS можно

разделить на три группы.

В первую группу флагов регистра EFLAGS/FLAGS входят 8 флагов состояния. Эти

флаги могут изменяться после выполнения машинных команд. Флаги состояния

регистра EFLAGS отражают особенности результата исполнения арифметических

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

лительного процесса и реагировать на него с помощью команд, условных перехо-

дов и вызовов подпрограмм. Флаг переноса (carry flag) CF:

1 — арифметическая операция произвела перенос из старшего бита резуль-

тата, старшим является 7-й, 15-й или 31-й бит в зависимости от размерности

операнда;

О — переноса не было.

Флаг четности (parity flag) PF:

1—8 младших разрядов (этот флаг только для 8 младших разрядов операн-

да любого размера) результата содержат четное число единиц;

0 — 8 младших разрядов результата содержат нечетное число единиц.

Вспомогательный флаг переноса (auxiliary carry flag) AF применяется только для

команд, работающих с BCD-числами. Фиксирует факт заема из младшей тет-

рады результата:

1 — в результате операции сложения был произведен перенос из разряда 3

в старший разряд или при вычитании был заем в разряд 3 младшей тетрады

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

0 — переносов и заемов в третий разряд (из третьего разряда) младшей тет-

рады результата не было.

Флаг нуля (zero flag) ZF:

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

О — результат ненулевой.

* Флаг знака (sign flag) SF отражает состояние старшего бита результата (биты 7,

15 или 31 для 8-, 16- или 32-разрядных операндов соответственно):

1 — старший бит результата равен 1;

0 — старший бит результата равен 0.

ж Флаг переполнения (overflow flag) OF используется для фиксации факта потери

значащего бита при арифметических операциях:

1 — в результате операции происходит перенос в старший знаковый бит ре-

зультата или заем из старшего знакового бита результата (биты 7,15 или 31

для 8-, 16- или 32-разрядных операндов соответственно);

0 — в результате операции не происходит переноса в старший знаковый бит

результата или заема из старшего знакового бита результата.

ш Уровень привилегированности ввода-вывода (Input/Output privilege level) IOPL

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

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

« Флаг вложенности задачи (nested task) NT используется в защищенном режиме

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

гую.

Во вторую группу флагов (группа флагов управления) регистра EFLAGS/FLAGS

входит всего один флаг направления (directory flag) DF. Он находится в десятом

бите регистра Е FLAGS и используется цепочечными командами. Значение флага DF

определяет направление поэлементной обработки в этих операциях: от начала

строки к концу (DF = 0) либо, наоборот, от конца строки к ее началу (DF =1). Для

работы с флагом DF существуют специальные команды CLD (снять флаг DF) и STD

(установить флаг DF). Применение этих команд позволяет привести флаг DF в со-

ответствие с алгоритмом и обеспечить автоматическое увеличение или уменьше-

ние счетчиков при выполнении операций со строками.

В третью группу флагов регистра EFLAGS/FLAGS входит 8 системных флагов,

управляющих вводом-выводом, маскируемыми прерываниями, отладкой, переклю-

чением между задачами и режимом виртуального процессора 8086. Прикладным

программам не рекомендуется модифицировать без необходимости эти флаги, так

как в большинстве случаев это ведет к прерыванию работы программы. Далее пе-

речислены системные флаги и их назначение.

II Флаг трассировки (trace flag) TF предназначен для организации пошаговой ра-

боты процессора:

1 — процессор генерирует прерывание с номером 1 после выполнения каж-

дой машинной команды (может использоваться при отладке программ,

в частности отладчиками);

0 — обычная работа.

Флаг прерывания (interrupt enable flag) IF предназначен для разрешения или

запрещения (маскирования) аппаратных прерываний (прерываний по входу

INTR):

1 — аппаратные прерывания разрешены;

О — аппаратные прерывания запрещены.

is Флаг возобновления (resume flag) RF используется при обработке прерываний

от регистров отладки.

И Флаг режима виртуального процессора 8086 (virtual 8086 mode) VM является

признаком работы процессора в режиме виртуального 8086:

1 — процессор работает в режиме виртуального процессора 8086;

О — процессор работает в реальном или защищенном режиме.

» Флаг контроля выравнивания (alignment check) AC предназначен для разреше-

ния контроля выравнивания при обращениях к памяти. Используется совместно

с битом AM в системном регистре CRO. К примеру, Pentium разрешает размещать

команды и данные начиная с любого адреса. Если требуется контролировать

выравнивание данных и команд по адресам, кратным 2 или 4, то установка дан-

ных битов приведет к тому, что все обращения по некратным адресам будут

возбуждать исключительную ситуацию.

Флаг виртуального прерывания (virtual interrupt flag) VIF, появившийся в про-

цессоре Pentium, при определенных условиях (одно из которых — работа про-

цессора в v-режиме) является аналогом флага IF. Флаг VIF используется совме-

стно с флагом VI Р.

ii Флаг отложенного виртуального прерывания (virtual interrupt pending flag) VIP,

появившийся в процессоре Pentium, устанавливается в 1 для индикации отло-

женного прерывания. Используется при работе в v-режиме совместно с флагом

VIF.

* Флаг идентификации (identification flag) ID используется для того, чтобы пока-

зать факт поддержки процессором инструкции CPUID. Если программа может

установить или сбросить этот флаг, это означает, что данная модель процессора

поддерживает инструкцию CPUID.

Уровни привилегий.

        Механизм защиты использует 4 уровня привилегий - от 0 до 3. Большее значение соответствует меньшим привилегиям. На рис. 2-1 показано, как эти уровни привилегий могут быть интерпретированы как кольца защиты. Центр, предназначенный для наиболее привилегированного кода, данных и стека, используется для сегментов, содержащих наиболее важные компоненты системы, такие, как ядро операционной системы. Внешние кольца используются для менее важных частей системы. Для систем, использующих только два из четырёх уровней привилегий, рекомендуется использовать уровни 0 и 3.

  Рисунок 2-1. Кольца защиты.

Примечания:

1.

"PL" означает "уровень привилегий" (сокращение от англ. Privilege Level).

2.

Синим цветом выделено рекомендуемое расположение компонентов операционной системы

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

Текущий уровень привилегий - CPL (Current privilege level). CPL - это уровень привилегий текущего исполняемого кода. Он хранится в битах 0 и 1 регистров CS и SS. Обычно, CPL равен уровню привилегий сегмента кода, из которого выбираются команды. Процессор меняет CPL, когда управление передаётся сегменту кода с другим уровнем привилегий. CPL интерпретируется немного иначе, когда управление передаётся подчинённому сегменту кода. Подчинённый сегмент кода доступен с тех уровней привилегий, которые численно не меньше, чем DPL подчинённого сегмента кода. CPL не меняется, когда происходит передача управления на подчинённый сегмент кода, имеющий уровень привилегий, отличный от CPL.

Запрашиваемый уровень привилегий - RPL (Requested privilege level). RPL - это уровень привилегий, назначаемый селекторам сегментов. Он хранится в битах 0 и 1 селектора сегмента. Процессор проверяет RPL совместно с CPL, определяя возможность доступа к сегменту. Даже если программа или задача, запрашивающая доступ к сегменту, имеет достаточные привилегии для доступа, доступ будет запрещён, если RPL не имеет достаточных привилегий. Таким образом, если RPL селектора сегмента численно превосходит CPL, то значение RPL будет решающим и наоборот. RPL можно использовать для обеспечения того, что привелигерованный код не обратится к сегменту от имени прикладной программы, пока эта программа не получит достаточных на то привилегий.

Уровень привилегий дескриптора - DPL (Descriptor privilege level). DPL - это уровень привилегий сегмента или шлюза. Он хранится в поле DPL дескриптора сегмента или шлюза. При попытке доступа из текущего сегмента кода к другому сегменту кода или шлюзу, DPL целевого дескриптора сравнивается с CPL и RPL. В зависимости от типа сегмента или шлюза, DPL интерпретируется следующим образом:

-

Сегмент данных. DPL определяет наибольший номер уровня привилегий, который программа или задача может иметь для доступа к этому сегменту. Например, если DPL сегмента данных равен 1, то только программы, работающие на уровнях 0 и 1 (т.е. имеющие CPL 0 или 1) могут обращаться к этому сегменту.

-

Неподчинённый (т.е. обычный) сегмент кода, без использования шлюза вызова. DPL определяет уровень привилегий, который должна иметь программа или задача для доступа к этому сегменту. Например, если DPL неподчинённого сегмента кода равен 0, то только программа, работающая на CPL = 0 может обратиться к этому сегменту.

-

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

-

Подчинённый или неподчинённый сегмент кода, доступный через шлюз вызова. DPL определяет наименьший номер уровня привилегий, который должна иметь программа или задача для доступа к этому сегменту. Например, если DPL подчинённого сегмента кода равен 2, то к нему будут иметь доступ только программы с CPL 2 или 3.

-

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

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

Проверка уровня привилегий при доступе к сегментам данных.

        Для доступа к операнду в сегменте данных, необходимо загрузить в сегментный регистр (DS, ES, FS или GS) селектор дескриптора сегмента данных. Для этого предназначены команды MOV, POP, LDS, LES, LFS и LGS.          Перед тем, как загрузить селектор в сегментный регистр, процессор проверяет уровень привилегий, сравнивая уровень привилегий текущего кода (CPL), RPL селектора и DPL дескриптора. Загрузка селектора производится, когда DPL больше либо равен CPL или RPL, иначе загрузка не произойдёт и процессор сгенерирует исключение общей защиты.

        Адресное пространство процедуры или задачи зависит от значения её CPL. Когда CPL = 0, доступны сегменты данных на всех уровнях привилегий, при CPL = 1 - на уровнях 1, 2 и 3, при CPL = 3 - только на 3-м уровне.          Прикладная программа может изменить RPL селектора, например, установить его в 0, и тогда проверка доступа будет осуществляться только по CPL.

Доступ к данным в сегменте кода.

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

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

Использовать префикс замены сегмента (CS) для чтения сегмента кода, разрешённого для чтения, чей селектор уже загружен в регистр CS.

Проверка уровня привилегий при загрузке регистра SS.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]