Команды сдвига выполняют арифметический или логический сдвиг над байтами, словами или двойными словами. Арифметический сдвиг вправо копирует знаковый бит в пустую позицию старшего бита операнда, в то время как логический сдвиг вправо, сдвинув операнд вправо, очищает пустые позиции. Арифметический сдвиг является самым быстрым способом выполнения простейших вычислений. Например, арифметический сдвиг вправо на один бит выполняет деление целого на два. Логический сдвиг делит целое без знака или положительное целое, но отрицательное целое со знаком теряет свой знаковый бит.
Команды арифметического и логического сдвига вправо, SAR и SHR, отличаются друг от друга только своей интерпретацией позиций битов, освобождаемых при смещении содержимого операндов. Обратите внимание, что нет различий в командах логического и арифметического сдвига влево. Два символьных имени, SAL и SHL, поддерживаются языком ассемблера для обозначения одной команды.
Счетчик указывает число битовых позиций, на которое надо сдвинуть операнд. Биты могут быть сдвинуты максимум на 31 позицию. Команды сдвига могут задавать счетчик сдвига любым из трех способов. Одна форма команд сдвига всегда выполняет сдвиг на один бит. Вторая форма задает счетчик сдвига как непосредственное значение. Третья форма задает счетчик как значение, содержащееся в регистре CL. Последняя форма позволяет задавать счетчик как результат вычислений. Используются только пять младших битов (разрядов) регистра CL.
Когда количество позиций сдвига равно нулю, никакие флаги не подвергаются изменениям. В противном случае флаг CF заполяется значением последнего бита, вытесненного за границы операнда. В командах сдвига на один бит флаг OF устанавливается равным единице, если значение самого старшего бита (знакового бита) изменяется в процессе операции. В противном случае флаг OF очищается (присваивается значение ноль). После сдвига более чем на одну позицию значение флага OF не определено. При сдвиге на одну или более позиций изменяются значения флагов SF, ZF, PF и CF, и состояние флага AF не определено.
SAL (Арифметический сдвиг влево) сдвигает байт, слово или двойное слово операнда назначения влево на одну позицию или на количество битов, заданное в операнде-счетчике (непосредственное значение или значение в регистре CL). Пустые биты очищаются. Смотри Рисунок 3-6.
SHL (Логический сдвиг влево) другое наименование команды SAL. Название поддерживается в языке ассемблера.
SHR (Логический сдвиг вправо) сдвигает байт, слово или двойное слово операнда назначения вправо на одну позицию или на количество битов, заданное в операнде-счетчике (непосредственное значение или значение в регистре CL). Пустые биты очищаются. Смотри Рисунок 3-7.
SAR (Арифметический сдвиг вправо) сдвигает байт, слово или двойное слово операнда назначения вправо на одну позицию или на количество битов, заданное в операнде-счетчике (непосредственное значение или значение в регистре CL). Знак операнда сохраняется путем очистки пустых позиций битов, если операнд положительный, или установки значений пустых битов (равным единице), если операнд отрицательный. Смотри Рисунок 3-8.
+-------------------------------------------------------------+| || Начальное состояние : || || CF ОПЕРАНД || +-+ +--------------------------------+ || |x| |10001000100010001000100010001111| || +-+ +--------------------------------+ || || После выполнения 1-разрядной (1-битовой) команды SHL/SAL : || || CF ОПЕРАНД || +-+ +--------------------------------+ || |1| |00010001000100010001000100011110| <- 0 || +-+ +--------------------------------+ || || После выполнения 10-разрядной (10-битовой) команды SHL/SAL :|| || CF ОПЕРАНД || +-+ +--------------------------------+ || |0| |00100010001000100011110000000000| <- 0 || +-+ +--------------------------------+ || |+-------------------------------------------------------------+ Рисунок 3-6. Команда SHL/SAL. +-------------------------------------------------------------+| || Начальное состояние : || || ОПЕРАНД CF || +--------------------------------+ +-+ || |10001000100010001000100010001111| |x| || +--------------------------------+ +-+ || || После выполнения 1-разрядной (1-битовой) команды SHR : || || ОПЕРАНД CF || +--------------------------------+ +-+ || 0 --> |01000100010001000100010001000111| --> |1| || +--------------------------------+ +-+ || || После выполнения 10-разрядной (10-битовой) команды SHR : || || ОПЕРАНД CF || +--------------------------------+ +-+ || 0 --> |00000000001000100010001000100010| --> |0| || +--------------------------------+ +-+ || |+-------------------------------------------------------------+ Рисунок 3-7. Команда SHR. +-------------------------------------------------------------+| || Начальное состояние (положительный операнд) : || || ОПЕРАНД CF || +--------------------------------+ +-+ || |01000100010001000100010001000111| |x| || +--------------------------------+ +-+ || || После выполнения 1-разрядной (1-битовой) команды SАR : || || ОПЕРАНД CF || +--------------------------------+ +-+ || +->|00100010001000100010001000100011| --> |1| || | +--------------------------------+ +-+ || +---+ || || Начальное состояние (отрицательный операнд) : || || ОПЕРАНД CF || +--------------------------------+ +-+ || |11000100010001000100010001000111| |x| || +--------------------------------+ +-+ || || После выполнения 1-разрядной (1-битовой) команды SАR : || || ОПЕРАНД CF || +--------------------------------+ +-+ || +->|11100010001000100010001000100011| --> |1| || | +--------------------------------+ +-+ || +---+ || |+-------------------------------------------------------------+ Рисунок 3-8. Команда SАR.
Насмотря на то, что эта команда может быть использована для деления целых на целое, являющееся степенью двойки, результат деления не будет тем же, что при выполнении команды IDIV. Частное при выполнении команды IDIV округляется в сторону нуля, в то время как "частное" при выполнении команды SAR округляется в сторону отрицательной бесконечности. Разница проявляется только для отрицательных чисел. Например, когда используется команда IDIV для деления -9 на 4, результатом будет -2 с остатком -1. Если использовать команду SAR для сдвига -9 вправо на два бита, результатом будет -3. "Остатком" такого вида деления будет -13; однако команда SAR сохраняет только бит старшего разряда остатка (во флаге CF).