Инструменты пользователя

Инструменты сайта


examination:asm:question18

Вопрос №18. Команды сдвига, их назначение и использование при программировании на ЯА. Примеры

Команды сдвига

Команды простого и циклического сдвигов

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

Логические и арифметические сдвиги

Операция сдвига битов целого числа может выполняться двумя способами. Первый называется логическим сдвигом, при котором «выдвинутая» позиция битового разряда заполняется нулем. На рис. 7.1 продемонстрирована операция логического сдвига байта на один разряд вправо. Обратите внимание, что в результате биту 7 присвоено нулевое значение.

Например, при выполнении логического сдвига вправо на один разряд байта, значение которого равно 11001111, получим число 01100111.

Второй тип сдвига называется арифметическим. Во время его выполнения «выдвинутая» позиция битового разряда заполняется первоначальным значением знакового разряда, как показано на рис. 7.2.

Например, байт, значение которого равно 11001111, имеет единицу в знаковом разряде. При выполнении арифметического сдвига его вправо на один разряд получим число 11100111.

Команда SHL

Команда SHL (SHift Left) выполняет логический сдвиг влево операнда получателя данных на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом младшие «выдвинутые» разряды заполняются нулями. Старший разряд числа помещается во флаг переноса CF, а бит, который до этого находился во флаге переноса, теряется.

Первый операнд команды SHL определяет сдвигаемое число, а второй — количество разрядов, на которые производится сдвиг:

SHL операнд, счетчик

Ниже приведены допустимые форматы операндов команды SHL:

SHL reg, imm8

SHL mem, imm8

SHL reg, CL

SHL mem, CL

Пример. В приведенном ниже фрагменте кода содержимое регистра BL сдвигается влево на один разряд. При этом старший бит помещается во флаг CF, а самый младший бит обнуляется:

mov bl, 8Fh ; BL = 10001111b

shl bl, 1 ; BL - 00011110b, CF - 1

Быстрое умножение. Чаще всего команда SHL используется для выполнения быстрого умножения некоторого числа на число, кратное 2n. В самом деле, сдвиг двоичного числа влево на n разрядов означает его умножение на 2n. Например, в результате сдвига числа 5 на один разряд влево получается число 10, т.е. произведение 5х2 (рис. 7.4):

Команда SHR

Команда SHR(SHift Right) выполняет логический сдвиг вправо операнда получателя данных на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом старшие «выдвинутые» разряды заполняются нулями. Младший разряд числа помещается во флаг переноса CF, а бит, который до этого находился во флаге переноса, теряется.

В команде SHR используются такие же форматы операндов, как и в команде SHL. В приведенном ниже фрагменте кода значение младшего бита регистра AL, равное нулю, помещается во флаг переноса СF, а старший бит регистра AL обнуляется:

mov al, 0D0h ; AL = 11010000b

shr al, 1 ; AL = 01101000b, CF = 0

Быстрое деление. Как вы уже знаете, сдвиг двоичного числа влево на п разрядов приводит к его умножению на 2n. Следовательно, сдвиг числа вправо на п разрядов должен приводить к его делению на 2n. Например, в результате сдвига вправо числа 32 на один разряд (т.е. на 21) получается число 16 :

Команды SAL и SAR

Команда SAL (Shift Arithmetic Left, или арифметический сдвиг влево) полностью эквивалента команде SHL, поскольку при сдвиге влево значение знакового разряда не сохраняется. Команда SAR (Shift Arithmetic Right) выполняет арифметический сдвиг вправо операнда получателя данных на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом старшие «выдвинутые» разряды заполняются прежним значением знакового разряда. Младший разряд числа помещается во флаг переноса CF, а бит, кото¬рый до этого находился во флаге переноса, теряется (рис. 7.7).

В командах SAL и SAR используются такие же форматы операндов, как и в командах SHL и SHR. Быстрое деление чисел со знаком. Команда SAR используется для выполнения быстрой операции деления некоторого числа на число, кратное 2n. В приведенном ниже примере число —128 делится на 8 (т.е. 23). Частное равно —16:

mov dl, -128 ; DL = 10000000b (-128)

sar dl, 3 ; DL = 11110000b (-16)

Команда ROL

Команда ROL (ROtate Left) циклически сдвигает каждый бит операнда получателя данных влево на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом старший бит числа копируется в младший бит, а также во флаг переноса CF (рис. 7.8). В команде ROL используются такие же форматы операндов, как и в команде SHL.

Циклический сдвиг отличается от простого сдвига тем, что в результате его выполнения значения битов числа не теряются, а просто перемещаются по кругу: старший бит помещается на место младшего, младший — на месте бита 1, затем бит 1 — на место бита 2 и т.д. В приведенном ниже примере значение старшего бита копируется в младший бит и во флаг переноса СF:

mov аl, 40h ; AL = 01000000b

rol аl, 1 ; AL = 10000000b, CF = 0

rol al, 1 ; AL = 00000001b, CF = 1

rol аl, 1 ; AL = 00000010b, CF = 0

Команду ROL можно использовать для обмена старшего (биты 4—7) и младшего (биты 0—3) полубайтов числа. Например, в результате циклического сдвига влево числа 26h получим число 62h:

mov al, 26h

rol al, 4 ; AL = 62h

Команда ROR

Команда ROR (ROtate Right) циклически сдвигает каждый бит операнда получателя данных вправо на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом младший бит числа копируется в старший бит, а также во флаг переноса CF . В команде ROR используются такие же форматы операндов, как и в команде SHR.

Команды RCL и RCR

Команда RCL(Rotate Carry Left) циклически сдвигает через флаг переноса каждый бит операнда получателя данных влево на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом значение флага переноса CF помещается на место самого младшего бита, а самый старший (знаковый) бит числа помещается во флаг переноса CF (рис. 7.10).

Если считать флаг переноса CF дополнительным разрядом числа, расположенным перед знаковым разрядом, то тогда команда RCL ничем не отличается от команды цикличе¬ского сдвига влево ROL, за исключением того, что она выполняется над 9-разрядным операндом.

Извлечение значения флага переноса CF. Команду RCL можно использовать для восстановления значения бита, который был ранее выдвинут во флаг переноса CF. В приведен¬ном ниже примере выполняется проверка значения младшего бита переменной testval путем его сдвига во флаг CF с помощью команды SHR. Последующая команда RCL восстанавливает первоначальное значение этого бита.

Команда RCR. Команда RCR (Rotate Carry Right) циклически сдвигает через флаг переноса каждый бит операнда получателя данных вправо на количество разрядов, указанных в исходном (т.е. втором) операнде. При этом значение флага переноса CF помещается на место самого старшего (т.е. знакового) бита, а самый младший бит числа помещается во флаг переноса CF .

Команды SHLD и SHRD

В отличие от рассмотренных выше команд сдвига, у этих команд не два, а три операнда.

Команда SHLD (SHift Left Double, или сдвиг влево удвоенный) выполняет логический сдвиг влево операнда получателя данных на количество разрядов, указанных в третьем операнде. Освободившиеся в результате сдвига разряды операнда получателя данных заполняются старшими битами исходного (т.е. второго) операнда. При этом значение исходного операнда не изменяется, но меняется состояние флагов знака SF, нуля ZF, служебного переноса AF, четности PF и переноса CF. Синтаксис команды SHLD следующий:

SHLD получатель, ИСТОЧНИК, счетчик

Команда SHRD (SHift Right Double, или сдвиг вправо удвоенный) выполняет логический сдвиг вправо операнда получателя данных на количество разрядов, указанных в третьем операнде.

формат операндов

SHLD reg16, reg16, CL/imm8 SHLD mem16, reg16, CL/imm8 SHLD reg32, reg32, CL/imm8 SHLD mem32, reg32, CL/imm8

Пример 1. В приведенном ниже фрагменте кода 16-разрядная переменная wval сдвигается на 4 бита влево. Освободившиеся младшие четыре разряда переменной wval заполняются четырьмя старшими разрядами регистра АХ (рис. 7.12):

.

Команды SHLD и SHRD часто используются для выполнения различных операций с растровыми изображениями, когда необходимо сдвинуть влево или вправо группу битов для перепозиционирования картинки на экране. Кроме того, данные команды можно с успехом применять в приложениях для шифрования данных, алгоритм работы которых построен на операциях сдвига группы битов. Наконец, эти две команды могут использоваться при выполнении операции быстрого умножения или деления целых чисел с очень большой разрядностью.

examination/asm/question18.txt · Последние изменения: 2014/01/15 12:12 (внешнее изменение)