Арифметический сдвиг – Учебный курс. Часть 18. Линейный сдвиг

Учебный курс. Часть 18. Линейный сдвиг

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

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

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

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

    shr ax,1         ;Логический сдвиг AX на 1 бит вправо
    shr byte[bx],cl  ;Лог. сдвиг байта по адресу BX на СL бит вправо
    shr cl,4         ;CL = CL / 16 (для числа без знака)

shr ax,1 ;Логический сдвиг AX на 1 бит вправо shr byte[bx],cl ;Лог. сдвиг байта по адресу BX на СL бит вправо shr cl,4 ;CL = CL / 16 (для числа без знака)

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

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

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

    sar bx,1         ;Арифметический сдвиг BX на 1 бит вправо
    sar di,cl        ;Арифметический сдвиг DI на CL бит вправо
    sar [x],3        ;x = x / 8 (x - 8-битное значение со знаком)

sar bx,1 ;Арифметический сдвиг BX на 1 бит вправо sar di,cl ;Арифметический сдвиг DI на CL бит вправо sar [x],3 ;x = x / 8 (x — 8-битное значение со знаком)

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

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

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

    shl dx,1         ;Сдвиг DX на 1 бит влево
    sal dx,1         ;То же самое
    shl ax,cl        ;Сдвиг AX на CL бит влево
    sal [x],2        ;x = x * 4

shl dx,1 ;Сдвиг DX на 1 бит влево sal dx,1 ;То же самое shl ax,cl ;Сдвиг AX на CL бит влево sal [x],2 ;x = x * 4

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

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

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

    shld ax,bx,3     ;Сдвинуть ax на 3 бита влево,
                     ;3 старших бита BX становятся младшими битами AX

shld ax,bx,3 ;Сдвинуть ax на 3 бита влево, ;3 старших бита BX становятся младшими битами AX

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use16                ;Генерировать 16-битный код
org 100h             ;Программа начинается с адреса 100h
    jmp start        ;Безусловный переход на метку start
;-- Данные ------------------------------------------------------------
v   dw 12345
pak db 13,10,'Press any key...$'
;----------------------------------------------------------------------
start:
    mov bx,[v]       ;BX = v
    mov ah,2         ;Функция DOS 02h - вывод символа
    mov cx,16        ;Инициализация счётчика цикла
lp:
    shl bx,1         ;Сдвиг BX на 1 бит влево
    mov dl,'0'       ;dl = '0'
    jnc print        ;Переход, если выдвинутый бит равен 0
    inc dl           ;dl = dl + 1 = '1'
print:
    int 21h          ;Обращение к функции DOS 02h
    loop lp          ;Команда цикла
 
    mov ah,9         ;\
    mov dx,pak       ; > Вывод строки 'Press any key...'
    int 21h          ;/
 
    mov ah,8         ;\
    int 21h          ;/ Ввод символа без эха
 
    mov ax,4C00h     ;\
    int 21h          ;/ Завершение программы

use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h jmp start ;Безусловный переход на метку start ;— Данные ———————————————————— v dw 12345 pak db 13,10,’Press any key…$’ ;———————————————————————- start: mov bx,[v] ;BX = v mov ah,2 ;Функция DOS 02h — вывод символа mov cx,16 ;Инициализация счётчика цикла lp: shl bx,1 ;Сдвиг BX на 1 бит влево mov dl,’0′ ;dl = ‘0’ jnc print ;Переход, если выдвинутый бит равен 0 inc dl ;dl = dl + 1 = ‘1’ print: int 21h ;Обращение к функции DOS 02h loop lp ;Команда цикла mov ah,9 ;\ mov dx,pak ; > Вывод строки ‘Press any key…’ int 21h ;/ mov ah,8 ;\ int 21h ;/ Ввод символа без эха mov ax,4C00h ;\ int 21h ;/ Завершение программы

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

Упражнение

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

Следующая часть »

asmworld.ru

4.1. Логические операции

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

Пример:

10001101  11110000 = 11111101.

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

i-м разряде находится единица, если оба операнда в этом i-м разряде имеются единицу, и ноль во всех других случаях.

Пример:

10001101  11110000 = 10000000

Операция суммирования по модулю 2 выполняется над двумя кодами и генерирует код той же разрядности, что и операнды, у которого в некотором i-м разряде находится единица, если два заданных операнда в i-м разряде имеют противоположные значения. Иногда эта операция называется «исключающее ИЛИ».

Пример

10001101  11110000 = 01111101.

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

Операции

сдвига в свою очередь, подразделяются на:

  • логические сдвиги, которые имеют разновидности – сдвиг вправо, сдвиг влево, циклический сдвиг вправо, циклический сдвиг влево;

  • арифметические сдвиги вправо и влево, выполнение которых зависит от знака и кода сдвигаемого числа.

4.2. Логические сдвиги

Сдвиг влево выполняется за счет установки в разряд значения, соответствующего исходному значению в ближайшем младшем разряде (освобождающийся самый правый т.е. самый младший, разряд заполняется 0, а «выталкиваемый» разряд пропадает). Например, код 11001110 после сдвига влево будет иметь вид 10011100.

Сдвиг вправо выполняется за счет установки в разряд значения, соответствующего исходному значению в ближайшем старшем разряде (в освобождающийся самый левый, т.е. самый старший, разряд заполняется 0, «выталкиваемый» разряд пропадает). Например, код 11001110 после сдвига влево будет иметь вид 01100111.

Циклический сдвиг влево выполняется за счет установки в разряд значения, соответствующего исходному значению в ближайшем младшем разряде (в освобождающийся самый правый, т.е. самый младший, разряд заносится значение старшего, т.е. самого левого разряда исходного кода). Например, код 11001110 после сдвига влево будет иметь вид 10011101.

Циклический сдвиг вправо выполняется за счет установки в разряд значения, соответствующего исходному значению в ближайшем старшем разряде (в освобождающийся самый левый т.е. самый старший, разряд заполняется значение в самом младшем разряде исходного кода). Например, код 11001110 после сдвига влево будет иметь вид 01100111.

4.3. Арифметические сдвиги

Арифметические сдвиги обеспечивают выполнение умножения (сдвиги влево) или операции деления (сдвиги вправо) двоичных кодов на два, точно так же, как сдвиги вправо и влево десятичного числа обеспечиваю выполнение деления и умножение на 10.

Арифметические сдвиги влево двоичного прямого кода выполняются в зависимости от того, какое сдвигается число – положительное или отрицательное.

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

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

Примеры

  1. Найти результат арифметического сдвига влево на три разряда двоичного прямого кода числа [А]пк= 00.00000101

Решение

Процесс выполнения заданного сдвига дает следующие промежуточные и конечное значения:

первый сдвиг: 00.00000101  00.00001010;

второй сдвиг: 00.00001010  00.00010100;

третий сдвиг: 00.00010100  00.00101000.

  1. Найти результат арифметического сдвига влево на четыре разряда двоичного прямого кода числа [А]пк= 00.00101.

Решение

Процесс заданного сдвига дает следующие промежуточные и конечное значения:

первый сдвиг: 00.00101  00.01010;

второй сдвиг: 00.01010  00.10100;

третий сдвиг: 00.10100  01.01000.

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

3. Найти результат арифметического сдвига вправо на два разряда двоичного прямого кода числа [А]пк = 00.00000110.

Решение

Процесс заданного сдвига дает следующие промежуточные и конечное значение:

первый сдвиг: 00. 00000110  00. 00000011;

второй сдвиг: 00. 00000011  00. 00000001;

После выполнения заданного количества сдвигов выполняется округление на основании последнего «вытолкнутого» разряда; в данном случае последний «вытолкнутый» разряд равен 1, поэтому конечный результат выполнения заданного сдвига будет равен

studfiles.net

Assembler: 30. Команды сдвига и циклического сдвига

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

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

SHL и SHR сдвигают биты операнда (регистр/память) влево или вправо соответственно на один разряд и изменяют флаг переноса cf. При логическом сдвиге все биты равноправны, а освободившиеся биты заполняются нулями. Указанное действие повторяется количество раз, равное значению второго операнда.

Пример: 
; al = 01011011 (двоичное) 
shr al, 3 

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

Команда shl такая же, как и shr, но сдвигает влево. 
; bl = 11100101 (двоичное) 
shl bl, 2 

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


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

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

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

Пример: 
; al = 10100110 
sar al, 3 
; al = 11110100 
sar al, 2 
; al = 11111101 

; bl = 00100110 
sar bl, 3 
; bl = 00000010

Команда SALсдвигает биты операнда (регистр/память) влево на один разряд, значение последнего вытолкнутого бита попадает в флаг переноса, а освободившиеся биты заполняются нулями, при этом знаковый бит не двигается.

Пример: 
; al = 10100110 
sal al, 3 
; al = 10110000
sal al, 4 
; al = 10000000


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

rol операнд, количество_сдвигов 
ror операнд, количество_сдвигов 
rcl операнд, количество_сдвигов 
rcr операнд, количество_сдвигов 

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

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

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

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

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

indigobits.com

Логический сдвиг — это… Что такое Логический сдвиг?

Би́товый сдвиг — изменение позиций битов в слове на одну и ту же величину.

В основной своей массе компьютеры не могут напрямую адресовать биты, которые содержатся группами по 8, 16, 32 битов в словах. Для обеспечения работы с битами существует множество команд, к которым относятся и сдвиги: Все сдвиги похожи друг на друга поведением средних битов: они просто сдвигаются влево или вправо на определённую величину. И различаются поведением крайних битов: одного, который уходит из слова, и второго, который должен появиться в слове.

Логический сдвиг

Логический сдвиг влево

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

Сдвиг, при котором уходящий бит уходит, не влияя на оставшееся биты, а на место появившегося бита записывается бит 0.

Пример работы операции сдвига:

Пусть у нас есть число 10101010b (в двоичной системе).
Если сделать сдвиг влево на 1 бит, то получим число 01010100b
Если сделать сдвиг вправо на 1 бит, то получим число 01010101b

В большинстве процессоров уходящий бит сохраняется в флаге переноса. Эта функция широко используется при работе с многобайтовыми числами.

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

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

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

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

Пример работы операции сдвига:

Пусть у нас есть число 11111010b=−6 (в двоичной системе).
Если сделать сдвиг влево на 1 бит, то получим число 11110100b=−12
Если сделать сдвиг вправо на 1 бит, то получим число 11111101b=−3

Легко заметить, что при арифметическом сдвиге сдвиг влево соответствует умножению на 2, а сдвиг вправо делению на 2 (в общем случае — на основание системы счисления). Исключение: −1 >>a 1 = −1 (в общем случае это относится к числам от −1 до −p+1, где p — основание системы счисления).

Схемотехническая реализация операций сдвига очень проста. Именно поэтому эти операции рекомендуют использовать для операций умножения и деления целых чисел на числа равные степени 2 (2, 4, 8, 16, 32, 64 и т. д.).

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

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

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

При этом сдвиге уходящий бит появляется на месте появившегося.

Пример работы операции сдвига:

Пусть у нас есть число 11111010b (в двоичной системе).
Если сделать сдвиг влево на 1 бит, то получим число 11110101b
Если сделать сдвиг вправо на 1 бит, то получим число 01111101b

Циклический сдвиг через бит переноса

Циклический сдвиг влево через бит переноса

Циклический сдвиг вправо через бит переноса

В архитектуру многих процессоров входит флаг переноса в следующий разряд (например, cf на n+1)-битным числом, состоящим из регистра и флага переноса.

Например, если у нас в регистре число 11111010b, флаг переноса равен 0:

После сдвига влево на 1 бит: в регистре 11110100b, флаг переноса равен 1
После сдвига вправо на 1 бит: в регистре 01111101b, флаг переноса равен 0

Операция циклического сдвига через бит переноса используется при работе с многобайтовыми числами. В частности, чтобы сдвинуть вправо на 1 бит длинное число, нужно очистить[1]cf (в случае деления числа со знаком нужно записать в cf старший бит старшего слова) и циклически сдвинуть на единицу через cf каждое слово, начиная с верхнего. Например, пусть у нас есть число 011000111100b, занимающее три 4-битных слова:

Было:              HI=0110, MED=0011, LO=1100, cf=0
После сдвига HI:   HI=0011, MED=0011, LO=1100, cf=0
После сдвига MED:  HI=0011, MED=0001, LO=1100, cf=1
После сдвига LO:   HI=0011, MED=0001, LO=1110, cf=0

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

Примечания

  1. Можно вместо очистки флага для первого обрабатываемого слова использовать арифметический\логический сдвиг, если он присваивает флагу cf значение вышедшего бита.

Источник

Wikimedia Foundation. 2010.

dic.academic.ru

Команды сдвига — Побитовая обработка

В программировании сдвигом называют одновременное перемещение границ расположения некоторой информации. Здесь можно провести хорошую аналогию с перемещениями, возникающими вследствие умножения или деления числа на какую-либо степень двойки. Пусть, например, некоторый байт содержит число 001000102. Сдвиг байта влево на 1 бит означает одновременное смещение всех его битов влево на 1 позицию.

Справа в освобождающийся разряд записывается 0. Первоначальное значение старшего разряда (разряда 0) теряется. Заметим, что, умножив исходное содержимое байта на 2, мы получили бы тот же результат.

Аналогично выполняются любые другие сдвиги. Рассмотрим в качестве еще одного примера сдвиг байта 10101110г на 3 разряда вправо.

В данном случае освободившиеся разряды располагаются в левом конце числа, содержимое же разрядов 5,6,7 утеряно. Заметим, что сдвиг не эквивалентен делению, если рассматривать содержимое байта как целое со знаком. Это очевидно, так как исходное число отрицательно, а результат положителен.

В ЭВМ Систем 360 и 370 возможны два типа сдвигов: арифметические и логические. Разница между ними заключается в обращении с содержимым знакового разряда. Сдвиги арифметического типа позволяют устранить возникшую в нашем последнем примере проблему сдвига знакового бита. Эти сдвиги обычно используются при обработке арифметической информации. Логические сдвиги выполняются так, как это и было описано выше, знаковый разряд в данном случае ничем не отличается от остальных.

Приведенные выше примеры касались сдвигов содержимого отдельных байтов. Необходимо отметить, что во всех ЭВМ Систем 360 и 370 все команды сдвига оперируют над содержимым регистров.

Логические сдвиги

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

Начнем наше рассмотрение с примера. Пусть содержимое регистра 5 в двоичной форме записывается как

10 1000 0111 0010 1001 1100 1111 0110

Команда

SLL 5,6

(Shift Left Logical — СДВИГ ВЛЕВО КОДА) производит сдвиг содер¬жимого регистра 5 на 6 разрядов влево. Результат ее выполнения вы-

глядит так:

(5)=ООО11100101001110011110110000000

формат команд сдвига является модификацией формата RS. Как обычно, первый операнд указывает регистр. Содержимое этого регистра (или регистров) будет сдвинуто в процессе выполнения команды. В обычных командах формата RS вторым операндом является адрес области памяти. Однако в командах сдвига этот операнд не используется для адресации. В качестве второго операнда выступает S-адрес, использующийся в данном случае не по своему обычному назначению. Последние 6 битов суммы

D2+(B2)

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

SLL R1,D2(B2)

Shift Left Logical

Сдвиг R1 влево наD2-f(B2) разрядов

SRL R1,D2(B2)

Shift Right Logical

Сдвиг (R1) вправо на D2+(B2) разрядов (учитываются последние6 разрядов)

Команды логического сдвига обычно используются для придания двоичной информации более компактной формы. Например, чтобы запомнить последовательность, состоящую из 100 чисел в форме полных слов, требуется 3200 битов памяти. Если известно, что все числа положительные и не превышают 64, то для хранения каждого числа на самом деле оказывается достаточно 6 битов, всего 600 битов для всей последовательности. (Если быть более точными, то при хранении 5 чисел в каждом полном слове потребуется всего 640 битов.) На рис. 14.4 изображен программный сегмент, выполняющий упаковку 5 таких чисел, первоначально находящихся в последовательных словах памяти, в регистр 7. Перед записью каждого следующего числа необходимо предварительно сдвинуть содержимое регистра 7 влево на шесть разрядов с тем, чтобы освободить место для вновь записываемого числа. Непосредственная запись может быть произведена с помощью команды О (ИЛИ). После ее выполнения число оказывается в последних шести разрядах регистра.

Рис. 14.4. Размещение в регистре 7 пяти 6-битовых чисел, расположенных в полных словах памяти, начиная с адреса NMBRS.

При проведении обратного преобразования (т. е. при переводе данных из компактной формы в обычную) удобно использовать сдвиг содержимого одного регистра в другой. Для этого предусмотрены две команды двойного сдвига: SLDL (Shift Left Double Logical — СДВИГ ВЛЕВО ДВОЙНОЙ КОДА) и SRDL (Shift Right Double Logical — СДВИГ ВПРАВО ДВОЙНОЙ КОДА).

SLDR R1,D2(B2)

Shift Left Double Logical

Сдвиг (R1.R1 + 1) влево на D2 + (B2) разрядов

SRDL R1,D2(B2)

Shift Right Double Logical

Сдвиг (R1.R1+1) вправо на D2 + (B2) (учитываются последние6 разрядов)

Здесь R1 на самом деле является ссылкой сразу на два регистра, R1 и R1 + 1. R1 при этом должен быть четным. При выполнении двойных сдвигов 64-разрядное содержимое двух регистров рассматривается как единое число. При левом сдвиге теряются старшие биты R1. Старшие биты R1 +1 занимают места в правом конце R1. Освобождающимися в данном случае являются младшие разряды R1 + 1.

Пусть регистры 4 и 5 содержат соответственно

(4) =0011 ООП ООН 0101 0110 0111 1000 1001

(5) = 1100 1011 1010 1001 1000 0111 0110 0101

По команде

SLDL 4,7

производится сдвиг содержимого регистров 4 и 5 влево на 7 разрядов. При этом теряются 7 старших разрядов регистра 4, содержимое 7 старших разрядов регистра 5 перемещается в 7 крайних правых разрядов регистра 4, и, наконец, 7 младших разрядов регистра 5 освобождаются и заполняются нулями. Итак, окончательно получается:

Двойной сдвиг вправо выполняется совершенно аналогично. Теряется содержимое младших разрядов R1 + 1. Биты из младших разрядов R1 попадают в старшие разряды R1 + 1. И, наконец, старшие разряды R1, освобождаясь, заполняются нулями.

Как уже упоминалось, двоичные сдвиги используются для «распаковки» двоичной информации. Предположим, что из слова BITDATA требуется выделить число, расположенное в битах 13—18, и затем записать его уже в обычной форме по адресу BITS. Приводимая ниже последовательность команд обеспечивает выполнение требуемых действий.

L 11,BITDATA

SLDL 10,13

LA 10,0

SLDL 10,5

ST 10,BITS

На рис. 14.5 приведен программный сегмент, предназначенный для «распаковки» содержимого регистра 7 (см. программу рис. 14.4) и записи результатов в форме полных слов последовательно, начиная со слова NMBRS.

Арифметические сдвиги

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

(9) =0000 1000 ООП 1101 0111 0010 0100 0010

Рис. 14.5. Размещение пяти 6-битовых чисел, находящихся в регистре 7, в последовательных словах памяти, начиная с адреса NUMBRS.

Выполнение команды

SLL 9,3

в данном случае эквивалентно умножению на 23=8, так как в результате получается

(9)=0100 0001 1110 1011 1001 0010 0001 0000

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

(9) = 1000 ООП 1101 0111 0010 0100 0110 0000

Итак, если следовать обычным правилам определения знака числа, то выйдет, что умножение на 16 может изменить знак числа (первоначальное содержимое регистра 9 было положительно, тогда как в результате нами получено число с противоположным знаком).

Устранить возникшие трудности можно с помощью команд арифметического сдвига. Арифметические сдвиги тем отличаются от логических, что при их выполнении содержимое знакового разряда сохраняется для обеспечения возможности дальнейшего нормального выполнения арифметических операций. Арифметический сдвиг не затрагивает знаковый бит. При сдвиге вправо разряды освобождаются, начиная с первого (знаковый разряд имеет номер 0). После выполнения сдвига в каждый из освободившихся разрядов заносится знаковый бит. Если, например, исходное число было положительным (его знаковый бит был равен 0), то при арифметическом сдвиге вправо освобождающиеся старшие разряды заполняются нулями. Если же исходное число было отрицательным, то происходит заполнение не нулями, а единицами. Проиллюстрируем сказанное на примере. Пусть сначала

(11)=0001 0010 0011 0100 0101 0110 0111 1000

itteach.ru

Арифметический сдвиг Википедия

Би́товый сдвиг — изменение позиций бит в машинном слове.

Большинство компьютеров не могут напрямую адресовать биты, которые содержатся группами по 8, 16, 32 или 64 бита в машинном слове. Для обеспечения работы с битами существует множество машинных инструкций, включающие различные типы сдвигов. Все сдвиги похожи друг на друга поведением средних битов, которые просто сдвигаются влево или вправо на определённую величину. Однако, поведение крайних битов, которые уходят из слова и которые появляются в слове, зависит от типа сдвига.

В электронике битовые сдвиги выполняются на сдвиговых регистрах.

Логический сдвиг

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

Сдвиг, при котором уходящий бит исчезает, не влияя на оставшиеся биты, а на месте появившегося бита записывается бит 0.

Пример работы операции сдвига:

  • Пусть у нас есть число 10101010b (в двоичной системе).
  • Если сделать сдвиг влево на 1 бит, то получим число 01010100b.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 01010101b.

В большинстве процессоров уходящий бит сохраняется во флаге переноса. Эта функция широко используется при работе с многобайтовыми числами.

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

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

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

Пример № 1

Пример работы операции сдвига 8 битного числа в прямом коде:

  • Пусть у нас есть 8 битное число: 00000010b = 2. (записанное в двоичной системе, в прямом коде).
  • Cдвиг влево на 1 бит, даёт число: 00000100b = 4.
  • Сдвиг вправо на 1 бит, даёт число: 00000001b = 1.

Пример № 2

Пример работы операции сдвига 8 битного числа записанного в дополнительном до 2х коде:

  • Пусть у нас есть число 11111010b = −6 (в двоичной системе, в дополнительном коде).
  • Если сделать сдвиг влево на 1 бит, то получим число 11110100b = −12.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 11111101b = −3.
Вывод

Легко заметить, что при арифметическом сдвиге сдвиг влево соответствует умножению на 2, а сдвиг вправо — делению на 2 (в общем случае — на основание системы счисления) с округлением к −∞. Например:

 1011 = −5          1111 = −1
>>a 1              >>a 1
 ----               ----
 1101 = −3          1111 = −1

Схемотехническая реализация операций сдвига очень проста. Именно поэтому эти операции рекомендуют использовать для операций умножения и деления целых чисел на числа, равные степени 2 (2, 4, 8, 16, 32, 64 и т. д.) — если, конечно, такое округление отрицательных чисел не мешает.

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

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

При этом сдвиге уходящий бит появляется на месте появившегося свободного на другом конце числа.

Пример

  • Пусть у нас есть число 11111010b (в двоичной системе).
  • Если сделать сдвиг влево на 1 бит, то получим число 11110101b.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 01111101b.

Циклический сдвиг через бит переноса

Циклический сдвиг влево через бит переноса Циклический сдвиг вправо через бит переноса

В архитектуру многих процессоров входит флаг переноса в следующий разряд (например, cf на x86). Данная операция выполняет циклический сдвиг над (n+1)-битным числом, состоящим из регистра и флага переноса.

Например, если у нас в регистре число 11111010b, флаг переноса циклического сдвига вправо равен 0.

  • После сдвига влево на 1 бит в регистре 11110101b, флаг переноса равен 1.
  • Далее, после сдвига вправо на 1 бит в регистре 01111101b, флаг переноса равен 1.

Операция циклического сдвига через бит переноса используется при работе с многобайтовыми числами. В частности, чтобы сдвинуть вправо на 1 бит длинное число, нужно очистить[1]cf (в случае деления числа со знаком нужно записать в cf старший бит старшего слова) и циклически сдвинуть на единицу через cf каждое слово, начиная с верхнего. Например, пусть у нас есть число 011000111100b, занимающее три 4-битных слова:

Было:              HI=0110, MED=0011, LO=1100, cf=0
После сдвига HI:   HI=0011, MED=0011, LO=1100, cf=0
После сдвига MED:  HI=0011, MED=0001, LO=1100, cf=1
После сдвига LO:   HI=0011, MED=0001, LO=1110, cf=0

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

См. также

Примечания

  1. ↑ Можно вместо очистки флага для первого обрабатываемого слова использовать арифметический\логический сдвиг, если он присваивает флагу cf значение вышедшего бита.

Ссылки

wikiredia.ru

Логический сдвиг Википедия

Би́товый сдвиг — изменение позиций бит в машинном слове.

Большинство компьютеров не могут напрямую адресовать биты, которые содержатся группами по 8, 16, 32 или 64 бита в машинном слове. Для обеспечения работы с битами существует множество машинных инструкций, включающие различные типы сдвигов. Все сдвиги похожи друг на друга поведением средних битов, которые просто сдвигаются влево или вправо на определённую величину. Однако, поведение крайних битов, которые уходят из слова и которые появляются в слове, зависит от типа сдвига.

В электронике битовые сдвиги выполняются на сдвиговых регистрах.

Логический сдвиг[ | ]

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

Сдвиг, при котором уходящий бит исчезает, не влияя на оставшиеся биты, а на месте появившегося бита записывается бит 0.

Пример работы операции сдвига:

  • Пусть у нас есть число 10101010b (в двоичной системе).
  • Если сделать сдвиг влево на 1 бит, то получим число 01010100b.
  • Если сделать сдвиг исходного числа вправо на 1 бит, то получим число 01010101b.

В большинстве процессоров уходящий бит сохраняется во флаге переноса. Эта функция широко используется при работе с многобайтовыми числами.

Арифметический сдвиг[ | ]

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

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

Пример № 1[ | ]

Пример работы операции сдвига 8 битного числа в прямом е:

  • Пусть у нас есть 8 битное число: 00000010b = 2. (записанное в двоичной системе, в прямом е).
  • Cдвиг влево на 1 бит, даёт число: 00000100b = 4.
  • Сдвиг вправо на 1 бит, даёт число: 00000001b = 1.

ru-wiki.ru

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *