Микропроцессоры 80386 серии iX86 фирмы Intel

Скачать доклад: Микропроцессоры 80386 серии iX86 фирмы Intel

ПРОЦЕССОР 80386

Новые инструкции

В процессоре 80386 введены следующие новые инструкции:

	       BSF     BTR     LFS     MOVZX
BSR BTS LGS SETxx
BT CDQ LSS SHLD
BTC CWDE MOVSX SHRD

Проверка битов

Инструкциями проверки битов процессора 80386 являются инструкции BT, BTC, BTR и BTS. Инструкция BT - это основная инструкция проверки битов, копирующая значение заданного типа во флаг переноса. Например, в следующем фрагменте программы переход на Bit3Is1 происходит только в том случае, если бит 3 регистра EAX отличен от 0:

        bt      eax,3
jc Bit3Is1
.
.
Bit3Is1:
.
.

Если EAX содержит значение 00000008h, то в этой программе произойдет переход на Bit3Is1. Если же EAX содержит значение 0FFFFFF7h, то переход выполнен не будет. Первый операнд инструкции BT представляет собой 16- или 32-разрядный общий регистр или ячейку памяти, содержащую проверяемый бит. Второй операнд - это номер проверяемого бита, заданный 8-битовым непосредственным значением или содержимым 16- или 32-разрядного общего регистра. Если в качестве второго операнд используется регистр, то его размер должен совпадать с размером первого операнда. Номер проверяемого бита может задаваться как регистром, так и непосредственным значением, а поле, в котором проверяется бит, может представлять со-
бой как ячейку памяти, так и регистр.

Инструкция BTC аналогична инструкции BT, только копируемое во флаг переноса значение представляет собой дополнение заданного бита. То есть флаг переноса устанавливается в значение 1, если заданный бит равен 0, и в значение 0, если заданный бит равен 1.

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

Инструкция BTR также аналогична инструкции BT, но после копирования проверяемого бита во флаг переноса его значение становится равным 0. Аналогично, инструкция BTS устанавливает проверяемый бит, копируемый во флаг переноса, в значение 1. Эти инструкции проверки полезно использовать для анализа и установки состояния флага в одной операции (при этом подразумевается, что не может произойти прерывание между проверкой флага и установкой его в новое значение).

Просмотр битов

Для нахождения первого или последнего ненулевого бита операнда размером в слово или двойное слово полезно использовать инструкции BSF и BSR. Инструкция BSF просматривает исходный операнд, начиная с бита 0 (младший бит), определяя первый ненулевой бит. Если все биты операнда-источника являются нулевыми, то флаг нуля очищается. В противном случае флаг нуля устанавливается, а в целевой регистр (приемник) копируется номер первого найденного ненулевого бита.

Второй операнд инструкции BFS - это 16- или 32-разрядный общий регистр или просматриваемая ячейка памяти, а первый операнд это 16- или 32-разрядный общий регистр, в который будет записываться номер первого ненулевого бита в просматриваемых данных.

Оба операнда должны иметь одинаковый размер.

Инструкция BSR аналогична инструкции BFS, но просмотр она начинает со старшего (наиболее значащего) бита операнда-источника к младшему биту.

Перемещение данных с расширением по знаку или нулю

Инструкции MOVZX и MOVSX позволяют вам копировать 8- или 16разрядное значение в 16- или 32-разрядный общий регистр без необходимости использования лишних инструкций для расширения значения до заданного размера. Инструкция MOVZX заполняет старшие биты приемника нулями, а инструкция MOVSX распространяет знак значения в соответствии с размером приемника. Обе инструкции аналогичны стандартной инструкции MOV.

Преобразование данных типа DWORD или QWORD

Для преобразования значений со знаком размером в байт в регистре AL в значения со знаком размером в слово и значений со знаком в регистре AL размером в слово в значения со знаком размером в двойное слово в процессоре 80386 предусмотрены соответственно инструкции CBW и CWD. В процессор 80386 добавлены еще две инструкции преобразования, CWDE и CDQ, которые облегчают работу с 32-разрядными регистрами процессора 80386.

Инструкция CWDE преобразует значение со знаком размером в слово, записанное в регистре AX, в значение со знаком размером в двойное слово, так же как инструкция CWD. Различие между этими двумя инструкциями состоит в том, что в то время как CWD помещает 32-разрядный результат в DX:AX, инструкция CWDE помещает помещает 32-разрядный результат в регистр EAX, который можно затем использовать в 32-разрядных инструкциях процессора 80386.

Инструкция CWD преобразует значение со знаком размером в двойное слово в регистре EAX в значение со знаком (8-байтовое) в EDX:EAX.

Сдвиг нескольких слов

Инструкции процессора 80386 SHRD и SHLD, обеспечивают сдвиг на несколько битов двух регистров или регистра и ячейки памяти.

Первый операнд инструкции SHLD - это 16- или 32-разрядный общий регистр или ячейка памяти, для которых нужно выполнить сдвиг.

Второй операнд представляет собой 16- или 32-разрядный регистр, в который нужно выполнить сдвиг, а третий операнд - это число битов, на которые нужно осуществить сдвиг. Размеры первого и второго операнда должны совпадать. Третий операнд должен представлять собой непосредственное значение или регистр CL. В последнем случае целевой операнд сдвигается на число битов, определяемый регистров CL.

Инструкция SHRD аналогична инструкции SHLD, однако она выполняет сдвиг из наиболее значащего (старшего) бита в направлении младших битов.

Условная установка битов

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

В процессоре 80386 для ускорения таких операций проверки и установки предусмотрена мощная группа инструкций SET.

Проверку в любом из знакомых вам условных переходах можно выполнить с помощью инструкции SET. Инструкция SETNC устанавливает целевой операнд в значение 1, если флаг переноса равен 0, и сбрасывает значение целевого операнда в 0, если флаг переноса равен 1. Инструкция SETS устанавливает приемник, если флаг знака равен 1, и сбрасывает его, если флаг знака равен 0 и т. д. Операнд инструкции SET может быть 8-битовым общим регистром или 8-битовой переменной в памяти. 16- и 32-разрядные операнды не допускаются.

Загрузка регистров SS, FS и GS

Инструкция процессора 8086 LDS позволяет вам загружать как регистр DS, так и один из общих регистров из памяти в одной инструкции, позволяя, таким образом, очень эффективно устанавливать дальние указатели. Инструкция LES обеспечивает аналогичную возможность, но вместо DS загружает регистр ES. В процессоре 80386 для загрузки дальних указателей добавлены инструкции LSS, LFS и LGS, которые загружают дальние указатели на основе сегментных регистров SS, FS и GS соответственно.

Расширенные инструкции

В процессор 80386 не только добавлены новые мощные инструкции по сравнению с набором инструкций процессором 8086/80186/80286, но также расширены имеющиеся инструкции. Это следующие инструкции:

        CMPS    JC      JNAE    JNLE    JPO     OUTS
IMUL JCXZ JNB JNO JS POPA
INS JE JNBE JNP JZ POPF
IRET JG JNC JNS LODS PUSHA
JA JGE JNE JNZ LOOP PUSHF
JAE JL JNG JO MOV SCAS
JB JLE JNGE JP MOVS STOS
JBE JNA JNL JPE

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

Специальные версии инструкции MOV

Процессор 80386 поддерживает специальные формы инструкции MOV, которые позволяют программе, работающей на уровень привилегий 0 (уровень с максимальными полномочиями) перемещать данные между 32-разрядными общими регистрами и специальными регистрами процессора 80386. Таким способом можно обращаться к следующим регистрам процессора 80386:

        CR0     DR0     DR3     TR6
CR2 DR1 DR6 TR7
CR3 DR2 DR7

32-разрядные версии инструкций процессора 8086

Многие инструкции процессора 8086 расширены таким образом, чтобы можно было использовать новые возможности адресации и новые операнды процессора 80386. Следующая инструкция выполняет 32-разрядное вычитание 32-битового регистра EBX из 32-битовой переменной по адресу EBP+EAX*8+10h. При этом для ссылки на целевую ячейку памяти используются 32-разрядные регистры:

sub     DWORD PTR [ebp+eax*8+10h],ebx

Новые версии инструкций LOOP и JCXZ

Инструкции LOOP, LOOPE, LOOPNE и JCXZ работают обычно с 16-разрядным регистром CX. Процессор 8086 предусматривает как 16разрядную, так и 32-разрядную версию этих инструкций. 32-разрядные версии вместо регистра CX могут работать с регистром ECX.

Инструкции LOOP, LOOPE и LOOPNE используют в качестве счетчика цикла регистр CX или ECX, в зависимости от типа сегмента (16 -битового или 32-битового). Если вы хотите обеспечить, чтобы в качестве регистра управления циклом всегда используется регистр CX (даже в 32-битовом сегменте), то используйте словную форму данных инструкций (LOOPW, LOOPWE или LOOPWNE). Аналогично, если нужно обеспечить использование в качестве управляющего циклом регистра регистр ECX, используйте следующие формы инструкций: LOOPD, LOOPDE и LOOPDNE.

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

Инструкция LOOPDE уменьшает содержимое ECX и выполняет переход на целевое смещение, пока флаг нуля равен 1, а ECX не равен 0. (LOOPDZ - это еще одна форма той же инструкции.) Аналогично, инструкция LOOPDNE уменьшает значение ECX и переходит по целевому смещению, пока флаг нуля равен 0, а ECX не равен 0. (LOOPDNZ это эквивалентная инструкция.)

Новые версии строковых инструкций

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

        CMPSD   MOVSD   SCASD
INSD OUTSD STOSD
LODSD

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

Инструкция IRETD

Инструкция IRETD аналогична инструкции IRET. Она извлекает из стека EIP, а затем CS, как двойное слово (отбрасывая старшее слово), после чего извлекает EFLAGS, как двойное слово.

Инструкции PUSHFD и POPFD

Инструкция PUSHFD заносит в стек полный 32-разрядный регистр флагов процессора 80386. Инструкция POPFD извлекает из стека полный 32-разрядный регистр флагов.

Инструкции же PUSHF и POPF заносят в стек и извлекают из него только младшие 16 битов регистра флагов.

Инструкции PUSHAD и POPAD

Инструкция PUSHAD заносит в стек восемь 32-разрядных общих регистров в следующем порядке: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI. Значение, заносимое для регистра ESP, соответствует значению регистра ESP в начале инструкции PUSHAD. Инструкция POPAD извлекает из стека семь 32-разрядных общих регистров в следующем порядке: EDI, ESI, EBP, EBX, EDX, ECX и EAX. Все эти регистры можно сохранить в стеке с помощью инструкции PUSHAD, а затем восстановить с помощью инструкции POPAD. Регистр ESP инструкцией POPAD не восстанавливается. Вместо этого выполняется выполняется увеличение на 32, чтобы отбросить блок из восьми 32-разрядных общих регистров, ранее сохраненный в стеке. Сохраненное ранее значение ESP игнорируется.

Новые версии инструкции IMUL

Дополнительно к формам инструкции IMUL, предусмотренным для процессоров 8086/80186/80286 в процессоре 80386 предусмотрена возможно самая удобная форма инструкции IMUL: любой общий регистр или ячейку памяти можно умножать на любой общий регистр, при этом результат снова сохраняется в одном из исходных регистров. Например, инструкция:

        imul    ebx,[edi*4+4]

умножает содержимое регистра EBX на значение размером в двойное слово, хранящееся по адресу памяти edi*4+4, а результат сохраняет снова в регистре EBX.

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

Как можно ожидать, в процессоре 80386 имеются также расширенные формы инструкции IMUL для процессоров 8086/80186/80286, поддерживающие 32-разрядные операнды. Например, в следующем коде ECX умножается на 1000000000h, а результат сохраняется в регистре EBP:

        imul    ebp,ecx,100000000h

а следующая инструкция умножает ECX на EBX, записывая результат в EDX:EAX:

      imul    ebx