Иллюстрированный самоучитель по Assembler

         

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

Содержание раздела