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

LEA <операнд l>, <операнд 2> ;вычисляет исполнительный адрес второго операнда и помещает его в поле, на которое указывает первый операнд.

Приведем примеры:

а) lea bx, exword- в регистр bx загружается исполнительный адресexword;

б) lea bx, [di+10] - в регистр bx загружается адрес l0-го байта относительно точки, на которую указывает адрес в регистре di.

Команды загрузки указателя.

LDS <регистр >,<операнд 2>

LЕS <регистр >,<операнд 2>

Команда LDS загружает в регистры DS :<регистр> указатель (< адрес сегмента> : <исполнительный адрес>), расположенный по адресу, указанному во втором операнде.

Команда LЕS загружает указатель по адресу, расположенному во втором операнде, в регистры ЕS:<регистр>.

Например:

lds si, exword;т.e. слово (2 байта) по адресу exword загружается в si, а по адресу exword+2 -в ds.

 

Команда записи в стек

На вершину стека всегда указывает регистр SP. Для обращения к данным в стеке, с использованием режимов адресации памяти, при которых указателем базы является регистр BP, можно использовать инструкцию MOV. Например, инструкция:

mov ax,[bp+4] ;загружает регистр AX содержимым слова в сегменте стека со смещением BP+4.

Однако чаще к стеку обращаются с помощью инструкций PUSH и POP.

PUSH <операнд> ;организует запись в стек слова, адрес которого указан в операнде.

Например:

push аx - запомнить содержимое регистра аx в стеке.

POP <операнд> ;организует чтение из стека последнего слова и помещает его по адресу, указанному во втором операнде.

Например:

pop аx - восстановить содержимое регистра аx из стека.

 

Например, инструкции:

mov ax,1

push ax

pop bx

заносят значение (равное 1) в регистре AX в вершину стека, затем извлекают 1 из вершины стека и сохраняют ее в BX.

 

Команда обмен данными

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

Например, инструкция:

xchg ax,dx ;выполняет обмен содержимого AX и DX, что эквивалентно выполнению инструкций:

push ax

mov ax,dx

pop dx

Команды сложения/ Команды вычитания

ADD <операнд 1>, <операнд 2>

ADC<операнд 1>, <операнд 2> ;устанавливают флаги четности, знака результата, наличия переноса, наличия переполнения.

Пo команде ADD выполняется сложение двух операндов. Результат записывается по адресу первого операнда. По команде АDC также выполнятся сложение двух операндов, но к ним добавляется еще значение, записанное в бите переноса, установленном предыдущей командой сложения.

Приведем пример сложения двух 32-разрядных чисел:

Mov ax,value1

Add value2,ax

mov ax,value1+2

adc value2+2,ax

Исходные числа находится в основной памяти по адресам value1и value2, а результат записывается по адресу value1.

SUB <уменьшаемое-результат>, <вычитаемое> ;

SBB<уменьшаемое-результат>,<вычитаемое>; устанавливают флаги четности, знака результата, наличия заема, наличия переполнения.

При выполнении операции по команде SUB заем не учитывается, а по команде SBB- учитывается. Ограничения на местоположение операндов такие же, как и у команды сложения.

Например, инструкции:

.DATA

BaseVal DW 99

Adjust DW 10

.CODE

mov dx,[BaseVal]

add dx,11

sub dx,[Adjust]

сначала загружают значение, записанное в BaseVal, в регистр DX, затем прибавляют к нему константу 11 (в результате в DX получается значение 110) и, наконец, вычитают из DX значение 10, записанное в переменной Adjust. Полученное в результате значение 100 сохраняется в регистре DX.

 

Команда изменения знака

NEG <операнд> ;знак операнда изменяется на противоположный.

Инструкции NEG, позволяет изменить (инвертировать) знак содержимого общего регистра или переменной в памяти.

Например, после выполнения инструкций:

mov ax,1 ; установить регистр AX в значение 1

neg ax ; отрицание AX, он становится равным -1

mov bx,ax ; скопировать содержимое AX в BX

neg bx ; отрицание BX, он становится равным 1

в регистре AX будет содержаться значение -1, а в регистре BX -значение 1.

Команда добавления /вычитания единицы

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

INC <операнд> ;значение операнда увеличивается на единицу.

DEC <операнд> ;значение операнда уменьшается на единицу.

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

СМP <операнд 1>, <операнд 2>; выполняется операция вычитания без записи результата и устанавливаются признаки во флажковом регистре.

Команды умножения/ деления

Процессор i86 может выполнять отдельные типы операций умножения и деления. Эта одна из сильных сторон процессора, поскольку во многих микропроцессорах вообще отсутствует непосредственная поддержка операций умножения и деления, а эти операции довольно сложно выполнить программным путем [38].

Инструкция MUL перемножает 8- или 16-битовые беззнаковые сомножители, создавая 16- или 32-битовое произведение. Давайте сначала рассмотрим умножение 8-битовых сомножителей.

При 8-битовом (8-разрядном) умножении один из операндов должен храниться в регистре AL, а другой может представлять собой любой 8-битовый общий регистр или переменную памяти соответствующего размера. Инструкция MUL всегда сохраняет 16-битовое произведение в регистре AX.

Например, во фрагменте программы:

mov al,25

mov dh,40

mul dh

AL умножается на DH, а результат (1000) помещается в регистр AX. Заметим, что в инструкции MUL требуется указывать только один операнд, другой сомножитель всегда храниться в регистре AL (или в регистре AX в случае перемножения 16-битовых сомножителей).

Инструкция перемножения 16-битовых сомножителей работает аналогично. Один из сомножителей должен храниться в регистре AX, а другой может находиться в 16-разрядном общем регистре или в переменной памяти. 32-битовое произведение инструкция MUL помещает в этом случае в регистры DX:AX, при этом младшие (менее значащие) 16 битов произведения записываются в регистр AX, а старшие (более значащие) 16 бит - в регистр DX.

Например, инструкции:

mov ax,1000

mul ax

загружают в регистр AX значение 1000, а затем возводят его в квадрат, помещая результат (значение 1000000) в регистры DX:AX.

В отличие от сложения и вычитания, в операции умножения не учитывается, являются ли сомножители операндами со знаком или без знака, поэтому имеется вторая инструкция умножения IMUL для умножения 8- и 16-битовых сомножителей со знаком. Если не принимать во внимание, что перемножаются значения со знаком, инструкция IMUL работает аналогично инструкции MUL.

Например, при выполнении инструкций:

mov al,-2

mov ah,10

imul ah

в регистре AX будет записано значение -20.

Процессор i86 позволяет с определенными ограничениями разделить 32-битовое значение на 16-битовое, или 16-битовое значение на 8-битовое. Рассмотрим деление 16-битового значения на 8-битовое.

При беззнаковом делении 16-битового значения на 8-битовое делимое должно быть записано в регистре AX. 8-битовый делитель может храниться в любом 8-битовом общем регистре или переменной в памяти соответствующего размера. Инструкция DIV всегда записывает 8-битовое частное в регистр AL, а 8-битовый остаток - в AH.

Например, в результате выполнения инструкций:

mov ax,51

mov dl,10

div dl

результат 5 (51/10) будет записан в регистр AL, а остаток 1 (остаток от деления 51/10) - в регистр AH.

Заметим, что частное представляет собой 8-битовое значение. Это означает, что результат деления 16-битового операнда на 8-битовый операнд должен превышать 255. Если частное слишком велико, то генерируется прерывание 0 (прерывания по делению на 0).

Инструкции:

mov ax,0fffh

mov bl,1

div bl

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

При делении 32-битового операнда на 16-битовый операнд делимое должно записываться в регистрах DX:AX. 16-битовый делитель может находиться в любом из 16-битовых регистров общего назначения или в переменной в памяти соответствующего размера.

Например, в результате выполнения инструкций:

mov ax,2

mov dx,1 ; загрузить в DX:AX 10002h

mov bx,10h

div bx

частное 1000h (результат деления 10002h на 10h) будет записано в регистре AX, а 2 (остаток от деления) - в регистре DX.

 

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

 

Рис. 3.5. Размещение сомножителей и результата

 

Рассмотрим пример:

Imul word ptr c

Здесь содержимое основной памяти по адресу «с» длиной слово умножается на содержимое регистра ax. Младшая часть результата операции записывается в регистр , а старшая часть - и регистр dx(рис. 3.5).

DIV <операнд-делитель>

IDIV <операнд-делитель>; по команде DIV операция деления выполняется без учета, а по команде IDIV - с учетом знака (в дополнительном коде).

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

Рис. 3.6 . Способы размещения делимого, делителя и результата