386+ BTR Проверка и сброс бита

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

Пример 1


mov AX,00Fh ;Анализируемое данное

btr АХ, 5 ;AX=00DFh. Бит 5 был = 1

;Сброс бита 5, ZF=1

Пример 2


mov AX,00FFh ;Анализируемое данное

btr AX, 8 ;AX=0FFh Бит 8 был =0

;Остался 0, ZF=0

Пример 3


mov AX,8001h ;Анализируемое данное

mov BX,15 ;Номер проверяемого бита

btr AX,BX ;AX=0001h Бит 15 был = 1

;Сброс бита 15, ZF=1

Пример 4


;В полях данных

mem dw IFh

;В программном сегменте: ;Анализируемое данное

btr mem,10 ;mem=lFh Бит 10 был = 0

;Остался 0, ZF=0

 

386+ BTS Проверка и установка бита


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

Пример 1


mov AX,OOFFh ;Анализируемое данное

bts AX, 5 ;AX=OOFFh Бит 5 был = 1

;Остался 1, ZF=1



Пример 2


mov AX,OOFFh ;Анализируемое данное

bts AX, 8 ;AX=lFFh Бит 8 был = 0

;Установка бита 8, ZF=0

Пример 3


mov AX,8001h ; Анализируемое данное

mov BX,15 ;Номер проверяемого бита

bts AX,BX ;AX=8001h Бит 15 был = 1

;Остался 1, ZF=1

Пример 4


; В полях данных

mem dw IFh ; Анализируемое данное

;В программном сегменте:

bts mem,10 ;mem=4lFh Бит 10 был = 0

; Установка бита 10, ZF=0

 

CALL Вызов подпрограммы


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


near ptr - прямой ближний вызов;

far ptr - прямой дальний вызов;

word ptr - косвенный ближний вызов;

dword ptr - косвенный дальний вызов.


Команда call прямого ближнего вызова заносит в стек относительный адрес точки возврата в текущем программном сегменте и модифицирует IP так, чтобы в нем содержатся относительный адрес точки перехода в том же программном сегменте. Необходимая для вычисления этого адреса величина смещения от точки возврата до точки перехода содержится в коде команды, который занимает 3 байт (код операции E8h и смещение к точке перехода).
Команда call прямого дальнего вызова заносит в стек два слова - сначала сегментный адрес текущего программного сегмента, а затем (выше, в слово с меньшим адресом) относительный адрес точки возврата в текущем программном сегменте. Далее модифицируются регистры IP и CS: в IP помещается относительный адрес точки перехода в том сегменте, куда осуществляется переход, а в CS - сегментный адрес этого сегмента. Обе эти величины берутся из кода команды, который занимает 5 байтов (код операции 9А1г, относительный адрес вызываемой подпрограммы и ее сегментный адрес).
Косвенные вызовы отличаются тем, что адрес перехода извлекается не из кода команды, а из ячеек памяти; в коде команды содержится информация о том, где находится адрес вызова. Длина кода команды зависит от используемого способа адресации.

Примеры прямого ближнего вызова


call near ptr subl ;Вызов подпрограммы subl

;из того же сегмента

call subl ;To же самое

Косвенные ближние вызовы

Пример 1


mov BX,offset subl ;ВХ=адрес подпрограммы

call BX ;Вызов подпрограммы

Пример 2


;
В полях данных:

addr dw subl ;Ячейка с адресом подпрограммы

;В программном сегменте:

call DS:addr ;Вызов подпрограммы

call word ptr addr ;To же самое

 

Пример 3


;В полях данных:

addr dw subl ;Ячейка с адресом подпрограммы

;В программном сегменте:

mov SI,offset addr ;SI=адрес ячейки с адресом

;подпрограммы

call [SI] ;Вызов подпрограммы

 

Пример 4


;В полях данных:
tbl dw subl ;Ячейка с адресом
;подпрограммы 1
dw sub2 ;Ячейка с адресом
;подпрограммы 2
dw sub3 ;Ячейка с адресом
;подпрограммы 3
;В программном сегменте:
mov BX,offset tbl ;ВХ=адрес таблицы адресов
;подпрограмм
mov SI, 2 ;SI=смещение к адресу sub2
call [BX] [SI] ;Вызов подпрограммы 2

Пример прямого дальнего вызова


call far ptr subl ;Вызов подпрограммы sub2,
;расположенной в другом

;программном сегменте

Косвенные дальние вызовы

Пример 1


;В полях данных:
addr dd subl ;Поле с двухсловным
;адресом подпрограммы
;В программном сегменте:
call DS:addr ;Вызов подпрограммы
call dword ptr addr;To же самое

Пример 2


;В полях данных:
addr dd subl ;Поле с двухсловным
;адресом подпрограммы
;В программном сегменте:
mov DI,offset addr ;В1=адрес поля с адресом
;подпрограммы
call [DI] ;Вызов подпрограммы

Пример 3


; В полях данных:
tbl dd subl ;Адрес подпрограммы 1
dd sub2 ;Адрес подпрограммы 2
dd sub3 ;Адрес подпрограммы 3
;В программном сегменте:
mov SI,offset tbl ;DI=адрес таблицы адресов
mov DI,8 ;Смещение к адресу sub3
call [SI] [DI] ;Вызов подпрограммы sub3

Допустимо использование дополнительных режимов адресации 32-разрядных процессоров. В 32-разрядных приложениях допустимо использование 32-битовых операндов. В защищенном режиме роль сегментного адреса выполняет селектор.

Примеры


call [EAX] ;Косвенный вызов

call 8[ЕСХ] ;Косвенный вызов

 

CBW Преобразование байта в слово


Команда cbw заполняет регистр АН знаковым битом числа, находящегося в регистре AL, что дает возможность выполнять арифметические операции над исходным операндом-байтом, как над словом в регистре АХ. Команда не имеет параметров и не воздействует на флаги процессора.

Пример 1

mov AL,5

cdw ;AX=0005h

Пример 2


mov AL, - 2 ;AL=FEh=-2 (байт)

cdv ;AX=FFFEh=-2 (слово)

 

386+ CDQ Преобразование двойного слова в четверное


Команда cdq расширяет знак двойного слова в регистре ЕАХ на регистр EDX. Эту команду можно использовать для образования четырехсловного делимого из двухсловного перед операцией двухсловного деления. Команда не имеет параметров и не воздействует на флаги процессора.

Пример 1


;В полях данных

mem dd -2 ; Отрицательное число

;В программном сегменте

mov ЕАХ,mem ;EAX=FFFFFFFEh

cdq ;EDX=FFFFFFFFh, EAX=FFFFFFFEh

Пример 2


;В полях данных

mem dd 7FFFFFFEh ,'Положительное число

;В программном сегменте

mov ЕАХ,mem ;EAX=7FFFFFFEh

cdq ;EDX=00000000h, EAX=7FFFFFFEh