Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
MOV
Влияние команды на флаги и форматы команды:
|
|
|
|
|
|
|
|
|
88 /r |
MOV r/m8,r8 |
r/m8 = r8 |
8086 |
mov [di],dl |
89 /r |
MOV r/m16,r16 |
r/m16 = r16 |
8086 |
mov [si],cx |
89 /r |
MOV r/m32,r32 |
r/m32 = r32 |
Intel386 |
mov [ebx],edi |
8A /r |
MOV r8,r/m8 |
r8 = r/m8 |
8086 |
mov dh,cl |
8B /r |
MOV r16,r/m16 |
r16 = r/m16 |
8086 |
mov dx,[di] |
8B /r |
MOV r32,r/m32 |
r32 = r/m32 |
Intel386 |
mov ebx,[edi] |
8C /r |
MOV r/m16,Sreg |
r/m16 = Sreg |
8086 |
mov dx,ds |
8E /r |
MOV Sreg,r/m16 |
Sreg = r/m16 |
8086 |
mov ds,si |
A0 |
MOV AL,moffs8 |
AL = [moffs8] |
8086 |
mov al,byteC |
A1 |
MOV AX,moffs16 |
AX = [moffs16] |
8086 |
mov ax,wordR |
A1 |
MOV EAX,moffs32 |
EAX = [moffs32] |
Intel386 |
mov eax,dwd |
A2 |
MOV moffs8,AL |
[moffs8] = AL |
8086 |
mov byteC,al |
A3 |
MOV moffs16,AX |
[moffs16] = AX |
8086 |
mov wordR,ax |
A3 |
MOV moffs32,EAX |
[moffs32] = EAX |
Intel386 |
mov dwd,eax |
B0+rb |
MOV r8,imm8 |
r8 = imm8 |
8086 |
mov dl,9 |
B8+rw |
MOV r16,imm16 |
r16 = imm16 |
8086 |
mov cx,3212 |
B8+rd |
MOV r32,imm32 |
r32 = imm32 |
Intel386 |
mov ebp,21367 |
C6 /0 |
MOV r/m8,imm8 |
r/m8 = imm8 |
8086 |
mov [di],2 |
C7 /0 |
MOV r/m16,imm16 |
r/m16 = imm16 |
8086 |
mov [di],2354 |
C7 /0 |
MOV r/m32,imm32 |
r/m32 = imm32 |
Intel386 |
mov [esi],985 |
Описание:
Команда MOV копирует второй операнд (операнд-источник) в первый операнд (операнд-назначение). Оба операнда могут быть регистрами общего назначения, сегментными регистрами, непосредственными значениями и переменными в памяти. Оба операнда должны иметь одинаковую размерность — байт, слово или двойное слово.
Если операнд-назначение — сегментный регистр (DS, ES, FS, GS или SS), тогда в скрытую часть этого регистра также загружаются данные из соответствующего дескриптора. Эти данные извлекаются из элемента таблицы дескрипторов для данного селектора. Сегментный регистр CS не может быть загружен командой MOV. Попытка использования соответствующего кода приводит к генерации особой ситуации #UD. Для загрузки регистра CS должны использоваться команды JMP, CALL или RET.
Пустой селектор (значения 0000, … 0003) может быть загружен в регистры DS, ES, FS и GS не вызывая особой ситуации. Однако попытка использования нулевых селекторов при обращении к памяти вызывает особую ситуацию #GP(0), и никакого обращения к памяти не происходит.
Ниже представлен листинг всех проверок и действий, предпринимаемых процессором при загрузке сегментного регистра в защищенном режиме:
IF (Загружается SS)
THEN
IF (Селектор не нулевой) THEN #GP(0); FI;
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
Поле RPL селектора должно быть равно CPL, иначе #GP(Селектор);
AR байт должен задавать сегмент данных, доступный для записи, иначе #GP(Селектор);
Поле DPL AR байта должно быть равно CPL, иначе #GP(Селектор);
Сегмент должен быть помечен, как присутствующий, иначе #SS(Селектор);
Загрузить SS селектором;
Загрузить SS дескриптором;
FI;
IF (загружается DS, ES, FS или GS не нулевым селектором)
THEN
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
AR байт должен задавать сегмент данных, или кодовый сегмент доступный для чтения, иначе #GP(Селектор);
IF (Данные или несогласованный код)
THEN RPL и CPL должны быть меньше или равны DPL в AR байте, иначе #GP(Селектор);
FI;
Сегмент должен быть помечен, как присутствующий, иначе #NP(Селектор);
Загрузить селектор в сегментный регистр;
Загрузить дескриптор в сегментный регистр;
FI;
IF (Загружается DS, ES, FS или GS нулевым селектором)
THEN
Загрузить селектор в сегментный регистр;
Очистить внутренний флаг корректности дескриптора (descriptor valid bit);
FI;
Команда загрузки сегмента стека SS запрещает все прерывания до завершения выполнения следующей команды (которая может быть командой MOV в ESP). Более эффективным методом загрузки нового указателя стека является команда LSS. Существуют и другие команды, которые задерживают прием прерываний при выполнении следующей за ними команды, но комбинация таких команд (например, STI и MOV SS,EAX) не означает, что прерывания не будут восприниматься на протяжении двух команд. Такие последовательности могут вызвать серьезные сбои, т.к. станет возможным поступление прерывания сразу после команды загрузки стекового сегмента SS.
В процессорах 32-разрядной архитектуры (Intel386, …) команды пересылки между сегментными регистрами и регистрами общего назначения не требуют наличия префикса 16-битного размера операнда (66h) не зависимо от текущего режима работы. Т.е. в этом случае всегда пересылаются 16-битные данные. Многие ассемблеры при встрече подобных мнемоник (например, MOV DS,AX) автоматически вставляют префикс 16-битного размера операнда перед командой пересылки. Это не влияет на результат исполнения команды, а замедляет только время исполнения. Простейшим выходом из данной ситуации является программирование 32-битной мнемоники (MOV DS,EAX), она преобразуется ассемблером в тот же самый код операции, но без префикса размера операнда. Поскольку пересылка данных в этом случае происходит межу 16-битным и 32-битным регистрами, то в 32-битном регистре в операции учавствуют только его младшие 16 бит. Если 32-битный регистр является операндом-назначением такой операции, то значения в его старших 16 битах после окончания пересылки могут быть различны в различных моделях процессоров. В Pentium Pro, … они заполняются нулями, а для более ранних процессоров Intel их значения не определены.
Операция:
DEST = SRC;
Особые ситуации защищенного режима:
#GP(0), если операнд-назначение находится в сегменте, запрещенном для записи, если используется некорректный эффективный адрес операнда в памяти в сегментах CS, DS, ES, FS, GS или нулевой селектор, а также при попытке загрузки регистра SS нулевым селектором.
#GP(Селектор), если индекс загруженного селектора не попадает в пределы таблицы дескрипторов, если при загрузке регистра SS запрашиваемый уровень привилегий селектора RPL или уровень привилегий соответствующего дескриптора сегмента DPL не равны текущему уровню привилегий CPL, если регистр SS загружается селектором, который указывает на сегмент запрещенный для записи, если регистр DS, ES, FS или GS загружается селектором сегмента, который не является доступным для чтения кодовым сегментом или сегментом данных, если регистр DS, ES, FS или GS загружается селектором сегмента, который является сегментом данных или несогласованным кодовым сегментом, и уровень привилегий дескриптора этого сегмента DPL меньше по значению запрашиваемого уровня привилегий селектора RPL и текущего уровня привилегий CPL.
#SS(0) при использовании некорректного эффективного адреса в сегменте SS.
#SS(Селектор), если регистр SS загружается селектором сегмента, который помечен как неприсутствующий.
#NP(Селектор), если регистр DS, ES, FS или GS загружается селектором сегмента, который помечен как неприсутствующий.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память при текущем уровне привилегий равном 3.
#UD при попытке загрузки регистра CS.
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда находится вне пространства эффективных адресов в сегментах CS, DS, ES, FS или GS.
#SS, если любая часть операнда находится вне пространства эффективных адресов в сегменте SS.
#UD при попытке загрузки регистра CS.
Особые ситуации режима V86:
Такие же, как и в режиме реальной адресации.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память.
Замечание:
В процессоре Pentium III существуют некоторые ситуации, когда отладчик будет получать неверную информацию в регистрах отладки от команд MOV SS и POP SS. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки.
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru