Материал: Системное программирование

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Рассмотрим примеры логического сдвига:

MOV AL, 01000111b

SHL AL, 1 ; CF=0 AL=10001110b

MOV AL, 01000111b

SHR AL, 1 ; CF=1 AL=00100011b

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

; op=op*2k(op - число со знаком и без)

MOV CL, k

SHL op, CL

Сдвиг на k разрядов вправо есть отбрасывание последних k разрядов, что соответствует получению неполного частного (операции div) от деления на 2k:

; ор=ор div 2k(op - число без знака)

MOV CL, k

SHR op, CL

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

Например, для умножения регистра AX на 10 можно выполнить следующие команды:

MOV BX, AX ; сохранить в BX содержимое регистра AX

SHL AX, 1 ; умножить AX на 2

SHL AX, 1 ; умножить AX на 4

ADD AX, BX ; умножить AX на 5

SHL AX, 1 ; умножить AX на 10

В следующем примере команда SHL используется для преобразования двух неупакованных двоично-десятичных чисел (старшая цифра находится в регистре BL, младшая – в регистре AL) в упакованное число в регистре AL:

MOV CL, 4 ; загрузить счетчик сдвига

SHL BL, CL ; сдвинуть старшую цифру влево на 4 бита

OR AL, BL ; объединить старшую и младшую цифры

Впоследствии команды простого сдвига дополнились еще двумя командами SHRDиSHLD. Они обеспечивают выполнение операций сдвига двойной точности. Команды имеют три операнда. Назначение первого операнда (приемника) и третьего операнда прежнее, а второй операнд (источник) должен быть только регистром и хранит старшую половину сдвигаемого числа. При выполнении сдвига по командеSHRDоперанд-приемник дополняется разрядами операнда-приемника, начиная с самого старшего разряда, а по командеSHLD– начиная с самого младшего разряда.

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

Команда SALпроизводит арифметический сдвиг содержимого операнда влево на указанное вторым операндом число разрядов (табл. 41). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Значение флага OF в операции многоразрядного сдвига и флага AF не определено. В операции одноразрядного сдвига флаг OF представляет результат операции «исключающее ИЛИ» между значением старшего разряда результата и содержимым флага CF после выполнения сдвига. Флаги SF, ZF и PF устанавливаются в соответствии с полученным результатом.

Табл. 41. Команда SAL.

Код

Инструкция

Описание

D0 /4

SAL r/m8, 1

Арифметический сдвиг r/m8 влево на 1 разряд.

D2 /4

SAL r/m8, CL

Арифметический сдвиг r/m8 влево на CL разрядов.

D1 /4

SAL r/m16, 1

Арифметический сдвиг r/m16 влево на 1 разряд.

D3 /4

SAL r/m16, CL

Арифметический сдвиг r/m16 влево на CL разрядов.

Команда SARпроизводит арифметический сдвиг содержимого операнда вправо на число разрядов, указанное вторым операндом (табл. 42). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Флаг OF сбрасывается, поскольку при арифметическом сдвиге вправо состояние старшего (знакового) разряда операнда никогда не изменяется. Флаги SF, ZF, AF и PF не изменяются.

Табл. 42. Команда SAR.

Код

Инструкция

Описание

D0 /7

SAR r/m8, 1

Арифметический сдвиг r/m8 вправо на 1 разряд.

D2 /7

SAR r/m8, CL

Арифметический сдвиг r/m8 вправо на CL разрядов.

D1 /7

SAR r/m16, 1

Арифметический сдвиг r/m16 вправо на 1 разряд.

D3 /7

SAR r/m16, CL

Арифметический сдвиг r/m16 вправо на CL разрядов.

Рассмотрим примеры арифметического сдвига:

MOV BH, 10001110b

SAR BH, 1 ; CF=0 ВН=11000111b

MOV BH, 00001110b

SAR BH, 1 ; CF=0 ВН=00000111b

Команда SAR может быть использована для быстрого получения неполного частного при делении знаковых чисел на степени 2. Однако она отличается от команды IDIV. Команда IDIV округляет частное в сторону 0, а SAR – в сторону минус бесконечности. Например, при делении -1 на 2 (при частном -0.5) команда IDIV выдаст ответ 0, а команда SAR -1. При делении неотрицательных чисел на степени 2, команда SAR даст тот же ответ, что и команды SHR, DIV и IDIV.

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

Команда ROLпроизводит циклический сдвиг содержимого своего операнда влево на указанное вторым операндом число разрядов (табл. 43). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Значение флага OF в операции многоразрядного сдвига не определено. Флаги SF, ZF, AF и PF не изменяются. В операции одноразрядного сдвига флаг OF представляет собой результат операции «исключающее ИЛИ» между значением старшего разряда результата и содержимым флага CF после выполнения сдвига.

Табл. 43. Команда ROL.

Код

Инструкция

Описание

D0 /0

ROL r/m8, 1

Циклический сдвиг r/m8 влево на 1 разряд через CF.

D2 /0

ROL r/m8, CL

Циклический сдвиг r/m8 влево на CL разрядов через CF.

D1 /0

ROL r/m16, 1

Циклический сдвиг r/m16 влево на 1 разряд через CF.

D3 /0

ROL r/m16, CL

Циклический сдвиг r/m16 влево на CL разрядов через CF.

Команда RORпроизводит циклический сдвиг содержимого своего операнда вправо на указанное вторым операндом число разрядов (табл. 44). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Значение флага OF в операции многоразрядного сдвига не определено. Флаги SF, ZF, AF и PF не изменяются. В операции одноразрядного сдвига флаг OF представляет собой результат операции «исключающее ИЛИ» между содержимым двух самых старших разрядов результата.

Табл. 44. Команда ROR.

Код

Инструкция

Описание

D0 /1

ROR r/m8, 1

Циклический сдвиг r/m8 вправо на 1 разряд через CF.

D2 /1

ROR r/m8, CL

Циклический сдвиг r/m8 вправо на CL разрядов через CF.

D1 /1

ROR r/m16, 1

Циклический сдвиг r/m16 вправо на 1 разряд через CF.

D3 /1

ROR r/m16, CL

Циклический сдвиг r/m16 вправо на CL разрядов через CF.

Приведем примеры применения двух последних команд:

MOV CL, 11000011b

ROL CL, 1 ; CF=1, CL=10000111b

MOV BH, 11100010b

ROR BH, 1 ; BH=01110001b, CF=0

Команды циклического сдвига обычно используются для перестановки частей содержимого ячейки или регистра. Например, поменять местами правую и левую половины регистра AL можно циклическим сдвигом байта на 4 разряда влево (или вправо):

MOV AL, 17h ; AL=00010111b

MOV CL, 4

ROL AL, CL ; AL=01110001b=71h

Команда RCLпроизводит циклический сдвиг содержимого своего операнда влево через флаг переноса на указанное вторым операндом число разрядов (табл. 45). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Значение флага OF в операции многоразрядного сдвига не определено. Флаги SF, ZF, AF и PF не изменяются. В операции одноразрядного сдвига флаг OF представляет собой результат операции «исключающее ИЛИ» между значением старшего разряда результата и содержимым флага CF после выполнения сдвига.

Табл. 45. Команда RCL.

Код

Инструкция

Описание

D0 /2

RCL r/m8, 1

Циклический сдвиг r/m8 влево на 1 разряд через CF.

D2 /2

RCL r/m8, CL

Циклический сдвиг r/m8 влево на CL разрядов через CF.

D1 /2

RCL r/m16, 1

Циклический сдвиг r/m16 влево на 1 разряд через CF.

D3 /2

RCL r/m16, CL

Циклический сдвиг r/m16 влево на CL разрядов через CF.

Команда RCRпроизводит циклический сдвиг содержимого своего операнда вправо через флаг переноса на указанное вторым операндом число разрядов (табл. 46). Флаг CF содержит значение последнего выдвинутого из операнда разряда. Значение флага OF в операции многоразрядного сдвига не определено. Флаги SF, ZF, AF и PF не изменяются. В операции одноразрядного сдвига флаг OF представляет собой результат операции «исключающее ИЛИ» между содержимым двух самых старших разрядов результата.

Табл. 46. Команда RCR.

Код

Инструкция

Описание

D0 /3

RCR r/m8, 1

Циклический сдвиг r/m8 вправо на 1 разряд через CF.

D2 /3

RCR r/m8, CL

Циклический сдвиг r/m8 вправо на CL разрядов через CF.

D1 /3

RCR r/m16, 1

Циклический сдвиг r/m16 вправо на 1 разряд через CF.

D3 /3

RCR r/m16, CL

Циклический сдвиг r/m16 вправо на CL разрядов через CF.

Пример команды циклического сдвига:

MOV BL, 11110000b ; пусть CF=0

RCL BL, 1 ; CF=1, BL=11100000b

RCL BL, 1 ; CF=1, BL=11000001b

Источник: https://files.student-it.ru/previewfile/284711