Jcc Команды условных переходов

Команды, обозначаемые (в книгах, не в программах!) Jcc, осуществляют переход по указанному адресу при выполнении условия, заданного мнемоникой команды. Если заданное условие не выполняется, переход не осуществляется, а выполняется команда, следующая за командой Jcc. Переход может осуществляться как вперед, так и назад в диапазоне + 127...-128 байтов.
В составе команд процессора предусмотрены следующие команды условных переходов:

Команда Перейти, если Условие перехода
ja выше CF=0 и ZF=0
jae выше или равно CF=0
jb ниже CF=1
jbe ниже или равно CF=1 или ZF=1
jc перенос CF=1
jcxz CX=0 CX=0
je равно ZF=1
jg больше ZF=0 или SF=OF
jge больше или равно SF=OF
jl меньше SF не равно OF
jle меньше или равно ZF=1 или SF не равно OF
jna не выше CF=1 или ZF=1
jnae не выше и не равно CF=1
jnb не ниже CF=0
jnbe не ниже и не равно CF=0 и ZF=0
jnc нет переноса CF=0
jne не равно ZF=0
jng не больше ZF=1 или SF не равно OF
jnge не больше и не равно SF не равно OF
jnl не меньше SF=OF
jnle не меньше и не равно ZF=0 и SF=OF
jno нет переполнения OF=0
jnp нет четности PF=0
jns знаковый бит равен О SF=0
jnz не нуль ZF=0
jo переполнение OF=1
jp есть четность PF=1
jpe сумма битов четная PF=1
jpo сумма битов нечетная PF=0
js знаковый бит равен SF=1
jz нуль ZF= I

Команды условных переходов, осуществляющие переход по условию "выше - ниже", предназначены для анализа чисел без знака; команды, осуществляющие переход по условию "больше - меньше", предназначены для анализа чисел со знаком.
Пример 1

cmp СХ,0 ;CX=0?
je equal ;Если да, перейти па метку equal
Пример 2

cmp AX,1000 ;Пусть AX=8000h=32768
;(=-32768)
ja above ;32768 > 1000. Переход будет
Пример 3

cmp AX,1000h ;Пусть AX=8000h=-32768
; (=32768)
jg greater ;-32768 < 1000h. Перехода не будет
Пример 4

int 21h ;Вызов системной функции
jc error ;Если CF=1 (ошибка), перейти
; на метку error
Команды условных переходов имеют варианты 16- и 32-разрядной адресации (при тех же мнемонических обозначениях) и могут передавать управление в диапазоне -32768...+32767 байт для сегментов с атрибутом размера 16 и в диапазоне -231...+231-1 байт для сегментов с атрибутом размера 32.
 
MP Безусловный переход
Команда jmp передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда не воздействует на флаги процессора.
Команда jmp имеет пять разновидностей:
- переход прямой короткий (в пределах -128... + 127 байтов);
- переход прямой ближний (в пределах текущего программного сегмента) ;
- переход прямой дальний (в другой программный сегмент);
- переход косвенный ближний;
- переход косвенный дальний.
Все разновидности переходов имеют одну и ту же мнемонику jmp, хотя и различающиеся коды операций. Во многих случаях транслятор может определить вид перехода по контексту, в тех же случаях, когда это невозможно, следует использовать атрибутные операторы:

short - прямой короткий переход;
near ptr - прямой ближний переход;
far ptr - прямой дальний переход;
word ptr - косвенный ближний переход;
dword ptr - косвенный дальний переход.
Примеры прямого короткого перехода

jmp short shpt ;Переход на метку shpt
;в пределах +127...-128 байтов
jmp shpt ;To же самое, если shpt
;находится выше по тексту программы
Примеры прямого ближнего перехода

jmp pt ;Переход на метку pt
;в пределах текущего сегмента
jmp near ptr pt ;To же самое
Примеры косвенных ближних переходов

Пример 1

mov BX,offset pt ;ВХ=адрес точки перехода
jmp BX ;Переход в точку pt
Пример 2

;В полях данных:
addr dw pt ;Ячейка с адресом точки перехода
;В программном сегменте:
jmp DS:addr ;Переход в точку pt
jmp word ptr addr ;To же самое
Пример 3

; В полях данных:
addr dw pt ;Ячейка с адресом точки перехода
;В программном сегменте:
mov DI,offset addr ;В1=адрес ячейки с адресом
;точки перехода
jmp [DI] ;Переход в точку pt
Пример 4

;В полях данных:
tbl dw ptl ;Ячейка с адресом 1
dw pt2 ;Ячейка с адресом 2
dw pt3 ;Ячейка с адресом 3
;В программном сегменте:
mov BX,offset tbl ;BX=aflpec таблицы адресов переходов
mov SI, 4 ;31=смещение к адресу pt3
call [BX][SI] ;Переход в точку pt3
Примеры прямых дальних переходов

jmp far ptr farpt ;Переход на метку farpt в
;другом программном сегменте
jmp farpt ;Переход на метку farpt в другом
;программном сегменте, если farpt
;объявлена дальней меткой
;директивой farpt label far
Примеры косвенных дальних переходов
Пример 1

; В полях данных:
addr dd pt ;Поле с двухсловным
;адресом точки перехода ;В программном сегменте:
jmp DS:addr ;Переход в точку pt
jmp dword ptr addr ;To же самое
Пример 2

; В полях данных:
addr dd pt ;Поле с двухсловным
;адресом точки перехода
;В программном сегменте:
mov DI,offset addr ;DI =адрес поля с адресом
;точки перехода jmp [DI] ;Переход в точку pt
Допустимо использование дополнительных режимов адресации 32-разрядных процессоров. Для 32-разрядных приложений допустимо использование 32-битовых операндов. В защищенном режиме вместо сегментного адреса сегмента (при дальних переходах) выступает его селектор.

LAHF Загрузка флагов в регистр АН


Команда lahf копирует флаги SF, ZF, AF, PF и CF соответственно в разряды 7, 6, 4, 2 и 0 регистра АН. Значение битов 5, 3 и 1 регистра АН не определено. Команда не имеет параметров и не изменяет флаги процессора.
Команда lahf (совместно с командой sahf) дает возможность читать и изменять значения флагов процессора, в том числе флагов SF, ZF, AF и PF, которые нельзя изменить непосредственно. Однако следует иметь в виду, что команда lahf переносит в АН только младший байт регистра флагов. Поэтому нельзя изменить с ее помощью, например, состояние флага OF.
Пример 1

lahf ;Регистр АН отображает
;состояние регистра флагов
or AH,80h ;Установка бита 7 = SF
sahf ;Загрузка АН в регистр
;флагов, где теперь SF = 1
Пример 2

lahf ;Регистр АН отображает
;состояние регистра флагов
and AH,0BFh ;Сброс бита 6 = ZF
sahf ;Загрузка АН в регистр
;флагов, где теперь ZF = О

386Р+ LAR Загрузка прав доступа


Команда lar загружает в первый операнд (16- или 32-разрядный регистр) поле атрибутов сегмента из дескриптора сегмента, заданного селектором во втором операнде. В качестве операнда с селектором может использоваться 16- или 32-разрядный регистр или ячейка памяти. В операнд-приемник поступают два байта атрибутов селектора с замаскированным полем старших битов границы сегмента.

LDS Загрузка указателя с использованием регистра DS


Команда Ids считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и загружает младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр DS. Таким образом, команда
Ids reg, mem
эквивалентна следующей группе команд:
mov reg,word ptr mem
mov DS,word ptr mem+2
В качестве первого операнда команды Ids указывается регистр общего назначения; в качестве второго - ячейка памяти с двухсловным содержимым. Указатель, содержащийся в этой ячейке, может быть адресом как процедуры, так и поля данных. Команда не воздействует на флаги процессора.
Пример 1

; В полях данных:
addr dd myproc ;Двухсловный адрес процедуры
;myproc
;В программном сегменте:
Ids SI,addr ;DS:SI -> myproc
Пример 2

; В полях данных:
mem dw 25 ;Ячейка памяти с
; произвольным содержимым
addr dd myproc ;Двухсловный адрес этой
;ячейки
;В программном сегменте:
mov BX,offset addr ;ВХ=адрес ячейки addr
Ids DX, [BX] ;DХ=смещение ячейки mem,
;DS=сегментный адрес ячейки
;mem
Пример 3

; В полях данных:
dptr dd procl ;Полный адрес процедуры
; р г о с 1
dd proc2 ;Полный адрес процедуры
;ргос2
dd ргосЗ ;Полный адрес процедуры
; р г о с 3
;В программном сегменте:
mov SI, 8 ; Смещение к адресу ргосЗ
Ids DI,dptr[SI] ;DS:DI ® ргосЗ
Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адресации 32-разрядных процессоров. В защищенном режиме вместо сегментного адреса сегмента выступает его селектор.

LEA Загрузка исполнительного адреса


Команда lea загружает в регистр, указанный в команде в качестве первого операнда, относительный адрес второго операнда (не значение операнда!). В качестве первого операнда следует указывать регистр общего назначения (не сегментный), в качестве второго - ячейку памяти. Команда
lea reg,mem
эквивалентна команде
mov reg,offset mem
но у первой команды больше возможностей описания адреса интересующей нас ячейки. Команда не воздействует на флаги процессора.
Пример 1

; В полях данных:
message db ; 'Идут измерения'
;В программном сегменте:
lea SI,message ;DS:SI -> message
Пример 2

; В полях данных:
nmb db '0123456789'
;В программном сегменте:
mov SI,7 ;Смещение символа '7'
lea DX,nmb[SI] ;ВХ=адрес символа '7'
Пример 3

; В полях данных:
nmb db '0123456789'
;В программном сегменте:
mov BX, off set msg
mov SI, 9 ;Смещение символа '9'
lea SI, [BX] [SI] ;31=адрес символа '9'
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.
386+ LEAVE Выход из процедуры высокого уровня
Команда leave выполняет действия, противоположные действиям последней команды enter. Она логически уничтожает созданный командой enter стековый кадр со всеми содержащимися в нем локальными переменными и подготавливает стек к выполнению команды irct, завершающей переход в вызывающую процедуру. Команда leave не имеет параметров. Более подробное описание и пример см. в описании команды enter.

LES Загрузка указателя с использованием регистра ES


Команда les считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и загружает младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр ES. Таким образом, команда
les reg,mem
эквивалентна следующей группе команд:
mov reg,word ptr mem
 mov ES,word ptr mem+2
В качестве первого операнда команды les указывается регистр общего назначения; в качестве второго - ячейка памяти с двухсловным содержимым. Указатель, содержащийся в этой ячейке, может быть адресом как процедуры, так и поля данных. Команда не воздействует на флаги процессора.
Пример 1

;В полях данных:
addr dd myproc ;Двухсловный адрес процедуры
;myproc
;В программном сегменте:
les SI,addr ;ES:SI ® myproc
Пример 2

;В полях данных:
mem dw 25 ;Ячейка памяти с
;произвольным содержимым
addr dd myproc ;Двухсловный адрес этой ячейки
;В программном сегменте:
mov BX,offset addr ;ВХ=адрес ячейки addr

les DX, [BX] ; DХ=смещение ячейки mem,
;ЕS=сегментный адрес ячейки mem
Пример 3

;В полях данных:
dptr dd procl ;Полный адрес процедуры prod
dd proc2 ;Полный адрес процедуры ргос2
dd ргосЗ ;Полный адрес процедуры ргосЗ
;В программном сегменте:
mov SI, 8 ;Смещение к адресу ргосЗ
les DI,dptr[SI] ;ES:DI -> ргосЗ
Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адресации 32-разрядных процессоров. В защищенном режиме вместо сегментного адреса сегмента выступает его селектор.

LFS Загрузка указателя с использованием регистра FS
LGS Загрузка указателя с использованием регистра FS
LSS Загрузка указателя с использованием регистра FS

Команды считывают из памяти полный указатель, состоящий из селектора и 16-битового или 32-битового смещения, и загружают младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр общего назначения, а старшую половину указателя (т.е. селектор) в сегментный регистр, указанный в мнемонике команды.
В качестве первого операнда всех перечисленных команд указывается 16- или 32-разрядный регистр общего назначения; в качестве второго - ячейка памяти с 32- или 48-битовым содержимым. Команда не воздействует на флаги процессора.
Примеры см. в описании команд Ids и les.
 
386Р+ LGDT Загрузка регистра таблицы глобальных дескрипторов
Команда Igdt загружает регистр таблицы глобальных дескрипторов (GDTR) из 48-битового псевдодескриптора, содержащего 32-битовый базовый адрес и 16-битовую границу таблицы глобальных дескрипторов, находящейся в памяти. В качестве операнда команды Igdt выступает относительный адрес псевдодескриптора.

386Р+ LIDT Загрузка регистра таблицы дескрипторов прерываний


Команда lidt загружает регистр таблицы дескрипторов прерываний (IDTR) из 48-битового псевдодескриптора, содержащего 32-битовый базовый адрес и 16-битовую границу таблицы дескрипторов прерываний, находящейся в памяти. В качестве операнда команды lidt выступает относительный адрес псевдодескриптора.

386Р+ LLDT Загрузка регистра таблицы локальных дескрипторов


Команда lldt загружает регистр таблицы локальных дескрипторов (LDTR) селектором, определяющим таблицу локальных дескрипторов (LDT). Селектор LDT должен входить в таблицу глобальных дескрипторов. В качестве операнда команды lldt, содержащего селектор LDT, можно использовать 16- или 32-разрядный регистр общего назначения или 16-или 32-битовое поле памяти.

386Р+ LMSW Загрузка слова состояния машины


Команда Imsw загружает в регистр слова состояния машины (так называется младшая половина управляющего регистра процессора CRO) слово состояния машины, взятое из указанного в команде операнда. В качестве операнда можно использовать 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти.
Команду Imsw можно использовать для перевода процессора из реального в защищенный режим или наоборот. В первом случае после чтения слова состояния командой smsw надо установить в нем бит 0 (бит РЕ) и загрузить назад в CRO командой Imsw. Во втором случае после после чтения слова состояния командой smsw надо сбросить в нем бит 0 и загрузить назад в CRO командой Imsw.

 
LOCK Запирание шины


Префикс lock, помещенный перед командой, устанавливает сигнал на линии LOCK системной шины и запрещает доступ к шине другим процессорам на время выполнения данной команды. Этот префикс предназначен для использования в многопроцессорных многозадачных системах для обеспечения исключительного доступа к памяти данного процесса (и данного процессора) на время проверки или модификации некоторой ячейки памяти. Типичный пример операций такого рода - работа с семафорами.
Если два (или более) процесса, идущие на разных процессорах, используют какой-либо общий ресурс, например, файл или лазерный диск, то необходимо обеспечить механизм, запрещающий одновременное обращение процессов к общему ресурсу. Эта задача решается с помощью семафора - ячейки памяти (байта или даже бита), состояние которого отражает доступность или, наоборот, занятость ресурса.
Если процессору понадобился общий ресурс, он читает состояние семафора и, если ресурс занят, продолжает опрашивать семафор до тех пор, пока другой процессор, использующий в настоящий момент общий ресурс, не освободит его. Обнаружив, что ресурс свободен, первый процессор устанавливает семафор в состояние "занят" и использует ресурс. Закончив работу с ресурсом, процессор сбрасывает его семафор и дает возможность другому процессу обратиться к тому же ресурсу.
Описанный алгоритм будет работать только в том случае, если операция чтения- модификации- записи семафора будет выполняться в непрерываемом режиме. В противном случае оба процесса могут, одновременно обратившись к семафору, увидеть, что ресурс свободен, и начать его совместное использование. Избежать такой ситуации и позволяет префикс lock в сочетании с командами типа btr или bts, выполняющими комплексные операции проверки и сброса или проверки и установки бита.
Будем считать, что семафор расположен в бите 0 байта по адресу sem, причем сброшенное состояние бита свидетельствует о занятости ресурса, а установленное состояние о том, что ресурс свободен. Тогда типичная процедура ожидания освобождения ресурса выглядит следующим образом:
mov SI,offset sem ;Адрес байта с семафором
getsem:
lock btr byte ptr [SI],1 ;Проверка и сброс бита 0
jnc getsem
Проверка состояния семафора и его модификация (запись в бит семафора 0, т.е. признака "занят") осуществляется в одной команде btr. На время выполнения этой команды шина многопроцессорной системы блокируется префиксом lock, и другой процессор обратиться к тому же семафору не может. Блокировка шины снимается уже после того, как семафор будет переведен в состояние занятости.
Если при обращении к байту sem оказывается, что в битс семафора записан 0, т.е. ресурс занят другим процессом, команда btr сбрасывает флаг CF (путем переноса в него содержимого анализируемого бита), что приводит к многократному повторению процедуры getsem, т.е. к циклу ожидания освобождения ресурса.
Типичная процедура освобождения занятого данным процессом ресурса выглядит следующим образом:
freesem:
lock bts byte ptr [SI],1 ;Проверка и установка бита 0
Собственно говоря, никакая проверка здесь не выполняется, однако процесс будет освобождать ресурс лишь если он этот ресурс использует, и проверять состояние флага в этой операции нет необходимости. Однако и здесь необходимо запирание шины на время записи в бит семафора 1, чтобы исключить одновременное обращение двух процессов к одной ячейке памяти.
386+ Префикс lock может быть использован только со следующими командами (и лишь при условии, что при их выполнении происходит обращение к памяти): adc, add, and, bt, bts, btr, btc, or, sbb, sub, xor, xchg, dec, inc, neg, not.

LODS Загрузка операнда из строки
LODSB Загрузка байта из строки
LODSW Загрузка слова из строки


Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они загружают в регистр AL (в случае операций над байтами) или АХ (в случае операций над словами) содержимое ячейки памяти по адресу, находящемуся в паре регистров DS:SI. Команда lodsb загружает 1 байт, команда lodsw - 1 слово, а команда lods может быть использована для загрузки как байтов, так и слов. В последнем случае размер загружаемого данного определяется описанием строки (с помощью директив db или dw). После операции загрузки регистр SI получает положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2, в зависимости от размера загружаемого элемента. Команда не имеет параметров и не воздействует на флаги процессора.
Вариант команды lods имеет формат
lods строка
(что не избавляет от необходимости инициализировать регистры DS:SI адресом строки). В этом формате возможна замена сегмента строки строка:
lods ES:строка
Пример 1

;В полях данных сегмента данных, адресуемого через DS:
str db 'qwertyuiop'
; В программном сегменте:
сld ;Двигаемся по строке вперед
mov SI, off set str ;Адрес строки
add SI,BX ;Добавим смещение (пусть ВХ=4)
lodsb ;AL='t', SI -> 'у'
Пример 2

;В полях данных сегмента данных, адресуемого через ES:
str db 'qwertyuiop'
;В программном сегменте:
сld ;Двигаемся по строке вперед
mov SI,offset str ;Адрес строки
lodsbES:str ;AL='q', ES:SI -> 'w'
386+ LODSD Загрузка двойного слова из строки
Команда аналогична командам МП 86 lodb и lodsw, но позволяет загрузить из строки, адресуемой через регистры DS:ESI (DS:SI для 16-разрядных приложений), двойное слово в регистр ЕАХ.
Пример

; В полях данных
dat dd 12789,200000,550000,8000000
;В программном сегменте
mov SI,offset dat
add SI, 4*3 ;DS:SI -> 4-й элемент массива чисел
lodsd ;EAX=8000000

LOOP Циклическое выполнение, пока содержимое СХ не равно нулю


Команда loop выполняет декремент содержимого регистра СХ, и если оно не равно 0, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128... + 127 байт. Обычно метка помещается перед первым предложением тела цикла, а команда loop является последней командой цикла. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536 (если перед входом в цикл СХ=0). Команда не воздействует на флаги процессора.
Пример 1

;В полях данных:
array dw 4096 dup (?) ;Массив из 4096 слов
;В программном сегменте:
lea BX,array ;ВХ -> array
xor SI,SI ;SI=0
mov CX,4096 ;Счетчик повторений
mov AX,1 ;Число-заполнитель
array: mov [BX] [SI],AX ;Очистка элемента массива
inc SI ;Сдвиг к следующему
inc SI ;слову массива
loop array ;Повторить СХ раз
Пример 2

mov CX,20
delay :loop delay ;Небольшая задержка
При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того чтобы в 16-разрядном приложении процессор при выполнении команды loop использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командой loop необходимо указать префикс замены размера адреса 67h.
Пример

mov ЕСХ,О
zzzz: db 67h ;Префикс замены размера адреса
loop zzzz ;Цикл из 232: шагов, реализующий
;программную задержку порядка минут

LOOPE/LOOPZ Циклическое выполнение, пока равно/циклическое выполнение, пока нуль


Оба обозначения представляют собой синонимы и относятся к одной команде. Команда выполняет декремент содержимого регистра СХ, и если оно не равно 0, и флаг ZF установлен, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128...+127 байтов. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536. Команда не воздействует на флаги процессора.
Пример

;В полях данных, адресуемых через DS:
command db 80 dup (' ')
;В программном сегменте:
. . . ;Копирование в поле command строки,
;содержимое которой следует анализировать
lea SI, command ;Настроим DS:SI
сld ;Обработка вперед
mov CX,80 ;Обрабатывать не более 80
;байтов
pass: lodsb ;Загрузим в AL очередной
;символ
сmр АL, ' ' ;Пропустим все пробелы в
loopepass ;начале строки
dec SI ;Сдвиг на 1 символ назад
;DS:SI -> первый символ, отличный от пробела
При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того, чтобы в 16-разрядном приложении процессор при выполнении команд loope/loopz использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командами loope/loopz необходимо указать префикс замены размера адреса 67h.
Пример

mov ЕСХ, 1000000 ;Предельное число шагов
хххх: ... ;Тело цикла
db 67h
loopexxxx

LOOPNE/LOOPNZ Циклическое выполнение, пока не равно/циклическое выполнение, пока не нуль


Оба обозначения представляют собой синонимы и относятся к одной команде. Команда выполняет декремент содержимого регистра СХ, и если оно не равно 0, и флаг ZF сброшен, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне -128... + 127 байтов. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536. Команда не воздействует на флаги процессора.
Пример

;В полях данных:
command db 80 dup (0)
;В программном сегменте:
. . . ;Копирование в поле command строки,
; содержимое которой следует анализировать
lea SI,command ;Настроим DS:SI
cld ;Обработка вперед
mov CX,80 ;Обрабатывать не более 80
;байтов
slash: lodsb ;Загрузим в AL очередной символ
cmp AL, ' / ' ;Ищем знак ' / '
loopne slash ;во всей строке
;DS:SI -> первый символ за знаком '/'
При использовании в качестве счетчика расширенного регистра ЕСХ максимальное число шагов в цикле увеличивается до 232. Для того чтобы в 16-разрядном приложении процессор при выполнении команд loopne/loopnz использовал не 16-разрядный регистр СХ, а 32-разрядный регистр ЕСХ, перед командами loopne/loopnz необходимо указать префикс замены размера адреса 67h.
Пример

mov ЕСХ,1000000 ;Предельное число шагов
хххх: . . . ;Тело цикла
db 67h
loopne xxxx

386Р+ LSL Загрузка границы сегмента


Команда Isl загружает в первый операнд границу сегмента из дескриптора сегмента, заданного селектором во втором операнде.
В качестве первого операнда команды Isl можно использовать 16- или 32-разрядный регистр общего назначения; в качестве второго - 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти.
386Р+ LTR Загрузка регистра задачи TR
Команда Itr загружает регистр задачи TR селектором сегмента состояния задачи TSS из второго операнда, в качестве которого можно использовать 16- или 32-разрядный регистр общего назначения или 16- или 32-битовое поле памяти. Команда используется в защищенном режиме, если программный комплекс выполнен в виде нескольких самостоятельных задач, и переключения между ними осуществляются с использованием включенных в процессор аппаратных средств поддержки многозадачности.

MOV Пересылка данных


Команда mov замещает первый операнд (приемник) вторым (источником). При этом исходное значение первого операнда теряется. Второй операнд не изменяется. В зависимости от описания операндов, пересылается слово или байт. Если операнды описаны по-разному или режим адресации не позволяет однозначно определить размер операнда, для уточнения размера передаваемых данных в команду следует включить один из атрибутных операторов byte ptr или word ptr. Команда не воздействует на флаги процессора. В зависимости от используемых режимов адресации, команда mov может осуществлять пересылки следующих видов:
- из регистра общего назначения в регистр общего назначения;
- из регистра общего назначения в ячейку памяти;
- из регистра общего назначения в сегментные регистры DS, ES и SS;
- из ячейки памяти в регистр общего назначения;
- из ячейки памяти в сегментный регистр;
- из сегментного регистра в регистр общего назначения;
- из сегментного регистра в ячейку памяти;
- непосредственный операнд в регистр общего назначения;
- непосредственный операнд в ячейку памяти.
Запрещены пересылки из ячейки памяти в ячейку памяти (для этого предусмотрена команда movs), а также загрузка сегментного регистра непосредственным значением, которое, таким образом, приходится загружать через регистр общего назначения:
mov AX,seg mem ;Сегментный адрес ячейки mem
mov DS,AX ;Загрузка его в регистр DS
Нельзя также непосредственно переслать содержимое одного сегментного регистра в другой. Такого рода операции удобно выполнять с использованием стека:
push DS
pop ES ; DS копируется в ES
Примеры

;В полях данных:
memb db 5,6
memd dd 0 ;Двухсловная ячейка
;В программном сегменте:
mov DX,AX ;Из регистра в регистр
mov AL,memb ;Из памяти в регистр
mov AX,0B800h ;Непосредственное значение в
;регистр
mov ES,AX ;Из регистра в сегментный
;регистр
mov word ptr memd+2,ES ;Из сегментного
;регистра в память
mov word ptr memd, 2000;Непосредственное
;значение в память
mov BX,word ptr memb ;Слово из памяти в
;регистр (число 0605)
mov DI,word ptr memd ;Слово из памяти в
;регистр
mov ES,word ptr memd+2;Слово из памяти в
;сегментный регистр
Допустимо использование 32-битовых операндов и дополнительных режимов адресации 32-разрядных процессоров.
Пример 1

mov EAX,ESI
Пример 2

; В полях данных
mem dd 0
;В программном сегменте
mov mem,EBP

386Р+ MOV Пересылка в\из специальных регистров


Этот вариант команды mov (с той же мнемоникой, но другими кодами операций) используется в защищенном режиме и предназначен для обмена данными со специальными регистрами процессора: управляющими CRO...CR3, тестирования TR6 и TR7, а также регистрами отладки DRO...DR7. Один из операндов команды mov должен быть 32-разрядным регистром общего назначения, другим - один из специальных регистров процессора.
 
MOVS Пересылка данных из строки в строку
MOVSB Пересылка байта данных из строки в строку
MOVSW Пересылка слова данных из строки в строку

Команды предназначены для операций над строками (строкой называется последовательность байтов или слов памяти с любым содержимым). Они пересылают по одному элементу строки, который может быть байтом или словом. Первый операнд (приемник) адресуется через ES:DI, второй (источник) - через DS:SI. Операцию пересылки можно условно изобразить следующим образом:
(DS:SI) -> (ES:DI)
После каждой операции пересылки регистры SI и DI получают положительное (если флаг DF=0) или отрицательное (если флаг DF=1) приращение. Величина приращения составляет 1 или 2 в зависимости от размера пересылаемых элементов. Вариант команды movs имеет формат:
movs строка_1, строка_2
В этом случае байты или слова из строки строка_2 пересылаются на место строки строка_]. Размер пересылаемых элементов определяется описанием строк (с помощью директив db или dw). Это не избавляет от необходимости инициализировать регистры ES:DI и DS:SI адресами строк строка _1 и строка_2. В этом формате возможна замена сегмента второй строки (источника):
movs строка_1, ES:строка_2
Рассматриваемые команды могут предваряться префиксом повторения rep (повторять СХ раз). После выполнения рассматриваемых команд регистры SI и DI указывают на ячейки памяти, находящиеся за теми (если DF=0) или перед теми (если DF=1) элементами строк, на которых закончились операции пересылки. Если флаг DF сброшен, то пары регистров DS:SI и ES:DI следует инициализировать начальными адресами строк-операндов; строка-источник будет пересылаться от се начала, в порядке возрастания номеров ее байтов. Если флаг DF установлен, то пары регистров DS:SI и ES:DI следует инициализировать конечными адресами строк-операндов; строка-источник будет пересылаться от ее конца, в порядке уменьшения номеров ее байтов. Команды не воздействует на флаги процессора.
Пример 1

;В полях данных основного сегмента данных,
;адресуемого через DS:
txt db 'Урок 1' ;Пересылаемая строка
txt_len equ S-txt ;Ee длина
;В 'полях данных дополнительного сегмента данных,
;адресуемого через ES :
string db 80 dup (' ')
;В программном сегменте:
lea SI,txt ;DS:SI -> txt
lea DI,string+10.;ES:DI -> string+10
сld ;Движение по строке вперед
mov CX,txt_len ;Столько байтов переслать
rep movsb ;Пересылка
Пример 2

;В полях данных сегмента данных, адресуемого через DS:
txt db 'А',84h, 'В',84h, 'A',84h, 'P',
db 84h,'И',84h,'Я',84h,'!',84h
txt_len=$-txt ;B программном сегменте:
mov AX,0B800h ;Сегментный адрес видеобуфера
mov ES,AX ;Инициализируем ES
;Выведем на экран текст
mov DI,1672 ;Смещение к середине экрана
lea SI,txt ;DS:SI ® txt
сld ;Движение по строке вперед
mov CX,txt_len/2 ;Столько слов переслать
rep movsw ;Пересылка в середину экрана
;красной мерцающей (атрибут
;84h) надписи 'АВАРИЯ!'
Пример 3

;В полях данных сегмента данных, адресуемого через DS:
datal dw 10000 dup(') ;Массив произвольных данных
data2 dw 5000 dup(') ;Массив-приемник
;В программном сегменте
push DS ;Настроим
pop ES ;ES на тот же сегмент данных
mov SI,offset datal;SI -> datal
add SI,5000 ;Сместим SI к середине
;массива
mov DI,offset data2;DI -> data2
mov CX,2500 ;Размер половины массива (в
;словах)
сld ;Движение вперед
rep movsw ;Перешлем вторую половину
;массива datal на место data2
Пример 4

;В полях данных сегмента, адресуемого через DS
file db 'MYFILE.01.DAT1,0 ;Строка-источник
fname db 128 dup(?) ;Строка-приемник
;В программном сегменте
push DS
pop ES ;Теперь ES=DS
mov SI,offset file;DS:SI -> strl
mov SI,128 ;Максимальная длина имени
;файла
сld ;Движение по строке вперед
null: lodsb ;Загрузим в AL очередной
; символ
cmp AL, 0 ;Ищем 0 в конце имени файла
loopne null
;DS:SI ® Первый символ за концом имени файла (за
;завершающим нулем)
dec SI ;SI -> байт с 0 std ;Движение по строке назад
mov ВХ,128 ;Из начального значения СХ
sub BX,CX ;вычтем то, что в СХ осталось
mov СХ,ВХ ;СХ=число символов в имени (с 0)
dec ВХ ;Смещение к 0 от начала имени файла
lea DI,fname[ВХ] ;Смещение завершающего 0
rep movsb ;Перешлем все имя (от конца к началу)

386+ MOVSD Пересылка двойного слова из строки в строку


Команда аналогична командам МП 86 movsb и movsw, но позволяет скопировать двойное слово из строки, адресуемой через регистры DS:ESI, в строку, адресуемую через регистры ES:EDI.
Пример 1

;В полях данных сегмента, адресуемого через DS
strl db '01234567890ABCDEF' ;Строка-источник
str2 db 16 dup(?) ;Строка-приемник
;B программном сегменте
push DS
pop ES ;Теперь ES=DS
mov SI,offset strl ;DS:SI ®strl
mov DI,offset str2 ;ES:DI -> str2
сld ;Движение по строке вперед
mov CX,4 ;Коэффициент повторения
rep movsd ;Копирование по 4*4 байт

386+ MOVSX Пересылка с расширением знака


Команда пересылает байт в слово или двойное слово, а также слово в двойное слово с расширением знака. В качестве первого операнда (приемника) может использоваться 16- или 32-разрядный регистр общего назначения, в качестве второго - 8- или 16-разрядный регистр общего назначения или ячейка памяти такого же размера. Недопустима пересылка из памяти в память, в или из сегментного регистра, а также непосредственного значения. Фактически команда movsx увеличивает размер как положительного, так и отрицательного числа, ни изменяя ни его значения, ни знака.
Пример 1

mov CL,-5 ;CL=FBh
movsxAX,CL ;AX=FFFBh
Пример 2

mov CL,+5 ;CL=05h
movsxAX,CL ;AX=0005h
Пример 3

mov BL,-128 ;BL=80h
movsxECX,BL ;ECX=FFFFFF80h
Пример 4

; В полях данных
mem dw -3 ;mem=FFFDh
;В программном сегменте
movsxEB-X,mem ; EBX=FFFFFFFDh

386+ MOVZX Пересылка с расширением нуля


Команда пересылает байт в слово или двойное слово, а также слово в двойное слово с заполнением старших разрядов нулями. В качестве первого операнда (приемника) может использоваться 16- или 32-разрядный регистр общего назначения, в качестве второго - 8- или 16-разрядный регистр общего назначения или ячейка памяти такого же размера. Недопустима пересылка из памяти в память, в или из сегментного регистра, а также непосредственного значения. Фактически команда movzx увеличивает размер числа, считая его числом без знака.
Пример 1

mov CL,5 ;CL=05h
movsxAX,CL ;AX=0005h
Пример 2

mov CL,-5 ;CL=FBh
movsxAX,CL ;AX=00FBh
Пример 3

mov BL,80h ;BL=80h
movsxECX,BL ;ECX=00000080h
Пример 4


;B полях данных
mem dw 0FFFFh ;mem=FFFFh
;B программном сегменте
movsxEBX,mem ;EBX=0000FFFFh

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика