Shr assembler что это

от admin

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

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

 команды линейного (нециклического) сдвига;

 команды циклического сдвига.

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

4.6.1. Команды линейного (нециклического) сдвига

Команды первой группы имеют следующий синтаксис:

SHR приемник,счетчик ; логический сдвиг вправо

SHL приемник,счетчик ; логический сдвиг влево

SAR приемник,счетчик ; арифметический сдвиг вправо

SAL приемник,счетчик ; арифметический сдвиг влево

Команды логического сдвига SHL и SHR сдвигают все биты операнда соответственно влево или вправо на столько бит, сколько указано в счетчике. При этом на место освобожденных разрядов вписываются нули.

mov al,57h ; al= 1010111b shl al,4

; Теперь al = 1110000b. Флаг переноса cf=0, т. к. последний выдвинутый слева бит был 0.

mov bh,5C ; bh= 1011100b shr bh,3

; Теперь bh=0001011b. Флаг переноса cf=1, т. к. последний выдвинутый слева бит был 1.

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

Команда SAL такая же, как SHL, а вот команда SAR имеет одно принципиальное отличие от SHR. Команда SAR не обнуляет самый левые (старшие) биты после сдвига, как это делает SHR, а заполняет их значением самого старшего бита операнда, т. е. команда SAR сохраняет знак числа.

mov al,57h ; al= 1010111b sal al,4

; Теперь al = 1110000b. Флаг переноса cf=0, т. к. последний выдвинутый слева бит был 0.

mov bl, B5 ; al = 10110101b sar bl, 3

; Теперь al = 11110110b. Флаг переноса cf=1, т. к. последний выдвинутый слева бит был 1.

mov dl,26h ; dl = 00100110b sar dl, 5

; Теперь dl = 0000001b. Флаг переноса cf=0, т. к. последний выдвинутый слева бит был 0.

Команды арифметического сдвига имеют одну уникальную особенность, которая часто используется программистами на ассемблере. Дело в том, что сдвиг влево

16. Линейный сдвиг в assembler

Статья основана на материале xrnd с сайта asmworld (из учебного курса по программированию на ассемблер 16-битного процессора 8086 под DOS).

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

Логический сдвиг вправо

Логический сдвиг всегда выполняется без учёта знакового бита. Для логического сдвига вправо предназначена команда SHR . У этой команды два операнда. Первый операнд представляет собой сдвигаемое значение и на его место записывается результат операции. Второй операнд указывает, на сколько бит нужно осуществить сдвиг. Этим операндом может быть либо непосредственное значение, либо регистр CL . Схема выполнения операции показана на рисунке:

Все биты операнда сдвигаются вправо (от старших битов к младшим). Выдвинутый бит становится значением флага CF . Старший бит получает нулевое значение. Эта операция повторяется несколько раз, если второй операнд больше единицы. Логический сдвиг вправо можно использовать для деления целых чисел без знака на степень 2, причём сдвиг работает быстрее, чем команда деления DIV . Примеры:

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

Арифметический сдвиг отличается от логического тем, что он не изменяет значение старшего бита, и предназначен для чисел со знаком. Арифметический сдвиг вправо выполняется командой SAR . У этой команды тоже 2 операнда, аналогично команде SHR . Схема выполнения операции показана на рисунке:

Выдвинутый бит становится значением флага CF . Знаковый бит не изменяется. При сдвиге на 1 бит сбрасывается флаг OF . Эту команду можно использовать для деления целых чисел со знаком на степень 2 (обратите внимание, что «округление» всегда в сторону меньшего числа, поэтому для отрицательных чисел результат будет отличаться от результата деления с помощью команды IDIV ). Примеры:

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

Логический сдвиг влево выполняется командой SHL , а арифметический — командой SAL . Однако, на самом деле это просто синонимы для одной и той же машинной команды. Сдвиг влево одинаков для чисел со знаком и чисел без знака. У команды 2 операнда, аналогично командам SHR и SAR . Схема этой операции показана на рисунке:

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

Сдвиги двойной точности

Существуют ещё две команды, осуществляющие более сложные сдвиги. SHRD — сдвиг двойной точности вправо, SHLD — сдвиг двойной точности влево. У этих команд 3 операнда. Первый операнд — сдвигаемое значение и место для записи результата, должен иметь размер 16 бит. Второй операнд — источник вдвигаемых битов, тоже должен иметь размер 16 бит и находится в одном из регистров. Значение второго операнда не меняется. Третий операнд — счётчик сдвигов, может быть непосредственным значением или находиться в регистре CL . Схемы работы этих команд показаны на рисунке:

Небольшой пример использования команды SHLD :

Пример программы

Программа печатает переменную размером 16-бит в двоичном виде. Используется команда сдвига влево на 1 бит, после чего анализируется значение флага CF . Если CF=0 , выводим символ ‘0’, если СF=1 выводим символ ‘1’. Проверка битов осуществляется в цикле.

Результат работы программы:

Упражнение

Объявите массив из 8 слов без знака. Сдвиньте первый элемент на 1 бит влево, второй элемент — на 2 бита вправо (логическим сдвигом), третий элемент — на 3 бита влево и т.д. до конца массива. Используйте циклы. Проверьте работу программы в отладчике. Результаты можете выкладывать в комментариях.

Shr assembler что это

shl %cl, r/m[8|16|32] sar imm8, r/m[8|16|32] sar %cl, r/m[8|16|32] shr imm8, r/m[8|16|32]

Operation

shift-left r/m[8|16|32] by imm8 -> r/m[8|16|32]

shift-left r/m[8|16|32] by %cl -> r/m[8|16|32]

Читать:
Alc888s vd что это

shift-right r/m[8|16|32] by imm8 -> r/m[8|16|32]

shift-right r/m[8|16|32] by %cl -> r/m[8|16|32]

Description

sal (or its synonym shl ) left shifts (multiplies) a byte, word, or long value for a count specified by an immediate value and stores the product in that byte, word, or long respectively. The second variation left shifts by a count value specified in the CL register. The high-order bit is shifted into the carry flag; the low-order bit is set to 0.

sar right shifts (signed divides) a byte, word, or long value for a count specified by an immediate value and stores the quotient in that byte, word, or long respectively. The second variation right shifts by a count value specified in the CL register. sar rounds toward negative infinity; the high-order bit remains unchanged.

shr right shifts (unsigned divides) a byte, word, or long value for a count specified by an immediate value and stores the quotient in that byte, word, or long respectively. The second variation divides by a count value specified in the CL register. shr sets the high-order bit to 0.

Example

Right shift, count specified by the constant (253), the 8-bit contents of the effective address (addressed by the ESI register plus an offset of 1):

Right shift, count specified by the contents of the CL register, the 16-bit contents of the effective address (addressed by the EDI register plus an offset of 4):

Left shift, count specified by the constant (253), the 32-bit contents of the effective address (addressed by the EDI register plus an offset of 4):

Ещё о командах ассемблера

Биты, сдвиг логический, арифметический и циклический

Обратите внимание: Большинство примеров ниже использует 8 битные числа, это сделано для того, чтобы вам было легче понять, как это работает.

Функции сдвига (сдвиг логический операнда влево/вправо)

Указанное выше действие повторяется количество раз, равное значению второго операнда.

Это означает: сдвиг всех битов регистра al на 3 разряда вправо. Так что al станет 00001011. Биты слева заполняются нулями, а биты справа выдвигаются. Последний выдвинутый бит, становится значением флага переноса cf.

Бит переноса это бит флагового регистра процессора. Этот регистр не такой как eax или ecx, к которому вы можете непосредственно обращаться (хотя есть опкоды, которые это делают), его содержание, зависит от результатов многих команд. Об этом я вам расскажу позже, единственное, что вы должны сейчас запомнить, это то, что флаг переноса это бит во флаговом регистре и что он может быть установлен (т.е. равен 1) или сброшен (равен 0).

Команда shl такая же, как и shr, но сдвигает влево.

После выполнения команды регистр bl будет равен 10010100 (двоичное). Два последних бита заполнились нулями, флаг переноса установлен, потому, что последний выдвинутый слева бит был равен 1

Здесь есть еще два других опкода: (сдвиг арифметический операнда влево/вправо)

Команда SAL такая же, как SHL, а вот SAR не совсем такая, как SHR. Команда SAR также, как и SHR сдвигает все биты операнда вправо на один разряд, при этом выдвигаемый справа бит становится значением флага переноса cf.

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

Циклический сдвиг

Циклический сдвиг напоминает смещение, выдвигаемые биты, снова вдвигаются с другой стороны:

Пример: команды ror (циклический сдвиг вправо)

Как видно из рисунка выше, биты вращаются, то есть каждый бит, который выталкивается снова вставляется с другой стороны. Флаг переноса cf содержит значение последнего выдвинутого бита.

RCL и RCR сдвигают все биты операнда влево (для RCL) или вправо (для RCR) на один разряд, при этом старший(для RCL) или младший(для RCR) бит становится значением флага переноса cf; одновременно старое значение флага переноса cf вдвигается в операнд справа(для RCL) или слева(для RCR) и становится значением младшего(для RCL) или старшего(для RCR) бита операнда. Указанные действия повторяются количество раз, равное значению второго операнда.

ROL и ROR сдвигают все биты операнда влево(для ROL) или вправо(для ROR) на один разряд, при этом старший(для ROL) или младший(для ROR) бит операнда вдвигается в операнд справа(для ROL) или слева(для ROR) и становится значением младшего(для ROL) или старшего(для ROR) бита операнда; одновременно выдвигаемый бит становится значением флага переноса cf. Указанные действия повторяются количество раз, равное значению второго операнда.

Стековые операции.

Иногда при вызове некоторых подпрограмм нужно сохранить все регистры для корректной работы программы в дальнейшем. Для этого вы будете последовательно сохранять каждый регистр в стеке и извлекать точно также:

Такой подход очень громоздок именно для этого и создана команда pushad. Она сохраняет все расширенные регистры в стеке. Соответственно команда popad нужна для извлечения из стека всех регистров.

Также есть команды для сохранения младших регистров pushaw и popaw. Они равносильны командам PUSH AX, CX, DX, BX, SP, BP, SI, DI и POP DI,SI,BP,BX,DX,CX,AX.

Иногда надо сохранять значения флагов после выполнения некоторой операции. Для этого нужны команды pushf и popf. Эти команды сохраняют в стеке значение регистра флагов или восстанавливают его оттуда.

Изменение флагов процессора.

  • CLC— установка CF=0
  • CLD— установка DF=0
  • CLI — установка IF=0
  • LAHF— загрузка регистра AH из регистра флагов: устанавливает биты 7, 6, 4, 2 и 0 по значениям флагов SF ZF AF PF CF.
  • SAHF— запись регистра AH в регистр флагов: устанавливает флаги SF ZF AF PF CF по битам 7, 6, 4, 2 и 0 регистра AH.
  • STC — установка CF=1
  • STD — установка DF=1
  • STI — установка IF=1

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

Похожие статьи