SAL – Shift Arithmetic operand Left – арифметический сдвиг операнда влево.

SAL операнд, количество_сдвигов

Флаги: SF, ZF, PF, CF. Флаг AF не определен. Флаг OF изменяется, если сдвиг осуществляется только на 1 разряд, иначе не определен. OF=1, если значение флага CF после сдвига и значение старшего бита результата различны, если совпадают – 0 (т.е. XOR от CF и старшего разряда результата).

Действие:

Сдвиг влево всех битов операнда. Каждый сдвиг влево эквивалентен умножению знакового числа на 2, поэтому команду удобно использовать для возведения операнда в степень 2. Старший бит операнда поступает в флаг CF. Если команда записана в формате:

SAL операнд, 1 - осуществляется сдвиг влево на 1 бит. В младший бит операнда загружается 0;

SAL операнд, CL - осуществляется сдвиг влево на число битов, указанное в регистре-счетчике CL. В процессе последовательных сдвигов старшие биты операнда, пройдя через флаг CF, теряются, а младшие заполняются 0;

16-ричный код (1 байт) MOD Reg/OPC Reg/Mem (2-ой байт) смещение disp_Lo, disp_Hi формат операндов: приемник, источник
D0 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg8/Mem8, 1
D1 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg16/Mem16, 1
D2 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg8/Mem8, CL
D3 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg16/Mem16, CL
C0 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg8/Mem8, imm8
C1 MOD 100 Reg/Mem Disp_Lo, Disp_Hi Reg16/Mem16, imm8

100 - расширение кода операции при работе с непосредственным операндом, размещается в поле Reg/Opc в байте адресации.

Например, 1) MOV AL, 7h

SAL AL, 1 ; AL=0Eh=7*2, CF=0

2) MOV AX, -1 ; AX=FFFFh

MOV CL, 4

SAL AX, CL ; AX=FFF0h= -1*16= -16, CF=1

4) SAR операнд, значение — арифметический сдвиг вправо (рис.1.21)

SAR – Shift Arithmetic operand Right – арифметический сдвиг операнда вправо.

SAR операнд, количество_сдвигов

Флаги: SF, ZF, PF, CF. Флаг AF не определен. Флаг OF=0, если сдвиг осуществляется только на 1 разряд, иначе не определен.

Действие:

Сдвиг вправо всех битов операнда. Младший бит операнда поступает в флаг CF. Освобождающиеся старшие разряды заполняются значением старшего (знакового) разряда. Каждый сдвиг вправо эквивалентен делению знакового числа на 2, поэтому команду удобно использовать для деления операнда на целые степени 2.

Коды команды см. таблицу команды SAL. Но расширение кода операции при работе с непосредственным операндом, размещающееся в поле Reg/Opc в байте адресации, равно 111.

Например, 1) MOV AL, 7h

SAR AL, 1 ; AL=3=7/2, CF=1. Остаток потерян.

2) MOV BX, -8 ; BX=FFF8h

MOV CL, 2

SAR BX, CL ; BX=FFFEh= -2= -8/4, CF=0

знак

 
  SAL – Shift Arithmetic operand Left – арифметический сдвиг операнда влево. - student2.ru

операнд CF

Рис. 1.21 Арифметический сдвиг вправо

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

Пример

MOV AL,11010100B

MOV CL,3

SAR AL,CL ; результат -11111010

MOV AL,11010100b

SHR AL,CL ; результат — 00011010 — ЗНАК ЧИСЛА ПОТЕРЯЛСЯ!

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

MUL (8-битный регистр) — 70— 77 тактов

(16-битный) —118—133 тактов

IMUL (8-битный регистр) — 80— 98 тактов

(16-битный) —128—154 тактов

IDIV (8-битный регистр) —101—112 тактов

(16-битный) —165—184 тактов

сдвиг регистра на 1 позицию — 2 такта

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

ПРИМЕР задания

Написать фрагменты программы для умножения X*12 двумя способами: с помощью команды умножения и с помощью сдвига. Оценить время выполнения каждого фрагмента.

X*12 = X * (23 + 22) = X * 23 + X * 22

Чтобы умножить число X на 12, нужно произвести сдвиг X влево на 3 бита, и результат где-то запомнить, затем произвести сдвиг X влево на 1 бит. Потом оба результата сложить.

x db 30 x db 30

.......... ..........

mov al,x mov al,x

cbw

mov cl,2 cbw

sal ax,cl ; ax=ax*4 mov bx,10; 2 такта

mov bx,ax imul bx; 128 тактов

SAL – Shift Arithmetic operand Left – арифметический сдвиг операнда влево. - student2.ru sal ax,1 ; ax=ax*2

add bx,axвсего 134 такта

 
  SAL – Shift Arithmetic operand Left – арифметический сдвиг операнда влево. - student2.ru

cbw, sal, mov — 2 такта

add — 3 такта

 
  SAL – Shift Arithmetic operand Left – арифметический сдвиг операнда влево. - student2.ru

всего 15 тактов

Таким образом, хоть первая программа и длинней, она будет выполняться намного быстрее (за 15 тактов), а вторая — за 134 такта. Отметим, что здесь не учитывается время для выборки переменной из сегмента данных.

5) ROL операнд, значение — сдвиг влево циклический (ROll Left) (рис.1.22)

Наши рекомендации