Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/2256: Рейтинг темы: голосов - 2256, средняя оценка - 4.63
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16374 / 7686 / 1080
Регистрация: 11.11.2010
Сообщений: 13,761
15.11.2013, 04:43  [ТС]
ГЛАВА 12
КОМАНДЫ СДВИГА
(часть 2/3)


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

Команда ROL

(Циклический сдвиг операнда влево = Rotate Operand Left)

Рис. 12.3.1. Схема работы команды ROL
Синтаксис команды:
ROL <DEST>,<COUNT>
Семантика команды: операция циклического сдвига операнда DEST влево.
Алгоритм работы:
  • сдвиг всех битов операнда DEST влево на один разряд, при этом старший бит операнда DEST вдвигается в операнд справа и становится значением младшего бита операнда;
  • одновременно выдвигаемый бит становится значением флага переноса CF;
  • указанные выше два действия повторяются количество раз, равное значению операнда COUNT. Количество битов может задаваться непосредственно в операнде COUNT или содержаться в регистре CL.
Возможные варианты команды:
rol mem/reg(8/16/32/64),count(cl/imm)
Применение:команда ROL используется для циклического сдвига разрядов операнда влево. Отличие этого сдвига от RCL в том, что очередной сдвигаемый бит одновременно вдвигается в операнд справа и становится значением флага CF. Так же, как и для других сдвигов, значение второго операнда (счетчика сдвига) ограничено диапазоном 0...63. Это объясняется тем, что микропроцессор использует только шесть младших разрядов операнда COUNT. Аналогично другим командам сдвига сохраняется эффект, связанный с поведением флага OF, значение которого имеет смысл только в операциях сдвига на один разряд:
  • если OF=1, то текущее значение флага CF и выдвигаемого слева бита операнда различны;
  • если OF=0, то текущее значение флага CF и выдвигаемого слева бита операнда совпадают.
Этот эффект, как Вы помните, обусловлен тем, что флаг OF устанавливается в единицу всякий раз при изменении знакового разряда операнда:
Assembler
1
2
3
MOV EAX,12345678h ;поменять местами половинки
MOV CL,16 ;регистра EAX
ROL EAX,CL ;EAX=56781234h
Команда ROR
(Циклический сдвиг операнда вправо= Rotate Operand Right)

Рис. 12.3.2. Схема работы команды ROR
Синтаксис команды:
ROR <DEST>,<COUNT>
Семантика команды: операция циклического сдвига операнда вправо.
Алгоритм работы:
  • сдвиг всех битов операнда вправо DEST на один разряд, при этом младший бит операнда вдвигается в операнд слева и становится значением старшего бита операнда;
  • одновременно этот младший бит операнда становится значением флага переноса CF;
  • старое значение флага переноса CF вдвигается в операнд слева и становится значением старшего бита операнда;
  • указанные выше два действия повторяются количество раз, равное значению операнда COUNT. Количество битов может задаваться непосредственно в операнде COUNT или содержаться в регистре CL.
Возможные варианты команды:
ror mem/reg(8/16/32/64),count(cl/imm)
Применение: команда ROR используется для циклического сдвига разрядов операнда вправо. Отличие этого сдвига от RCR в том, что очередной сдвигаемый бит одновременно вдвигается в операнд слева и становится значением флага CF. Так же, как и для других сдвигов, значение операнда COUNT (счетчика сдвига) ограничено диапазоном 0...63. Это объясняется тем, что микропроцессор использует только шесть младших разрядов операнда COUNT. Аналогично другим командам сдвига сохраняется эффект, связанный с поведением флага OF, значение которого имеет смысл только в операциях сдвига на один разряд:
  • если OF=1, то текущее значение флага CF и вдвигаемого слева бита операнда различны;
  • если OF=0, то текущее значение флага CF и вдвигаемого слева бита
    операнда совпадают.
Этот эффект обусловлен тем, что флаг OF устанавливается в единицу всякий раз при изменении знакового разряда операнда.
Assembler
1
2
3
;поместить четыре младших бита AX на место старших битов
MOV AX,1234h
ROR AX,4; AX=4123h
Команда RCL
(Циклический сдвиг операнда влево через флаг переноса =
“Rotate operand through Carry flag Left”)
Синтаксис команды:
RCL <DEST>,<COUNT>
Семантика команды: операция циклического сдвига операнда влево через флаг переноса CF.

Рис. 12.3.3. Схема работы команды RCL
Возможные варианты команды:
rcl mem/reg(8/16/32/64),count(cl/imm)
Алгоритм работы
:
  • сдвиг всех битов операнда DEST влево на один разряд, при этом старший бит операнда становится значением флага переноса CF;
  • одновременно старое значение флага переноса CF вдвигается в операнд справа и становится значением младшего бита операнда;
  • указанные выше два действия повторяются количество раз, равное значению операнда COUNT команды RCL. Количество битов может задаваться непосредственно в операнде COUNT или содержаться в регистре CL.
В случае команды RCL флаг OF представляет интерес, если сдвиг осуществляется на один разряд.
Применение: команда RCL используется для циклического сдвига разрядов операнда влево. Особенность этого сдвига в том, что он происходит с некоторой задержкой, так как очередной сдвигаемый бит оказывается на некоторое время вне операнда. В это время можно произвести его извлечение и (или) подмену. Другой важный момент заключается в том, что для счетчика сдвига микропроцессор использует только шесть младших разрядов операнда COUNT. Таким образом, значение, большее 64, микропроцессором не допускается (аппаратно это ограничение реализуется тем, что игнорируются значения всех битов счетчика, кроме первых шести). Обратите внимание на еще один интересный эффект, связанный с поведением флага OF. В операциях сдвига на один разряд по изменению этого флага можно судить о факте изменения знакового (старшего) разряда операнда:
  • OF=1, если текущее значение флага CF и выдвигаемого бита операнда слева различны;
  • OF=0, если текущее значение флага CF и выдвигаемого бита операнда слева совпадают.
Assembler
1
2
3
4
5
6
7
8
;сдвиг операнда, занимающего два двойных слова на четыре разряда влево
MOV ECX,4 ;счетчик сдвигов в ECX
MOV EAX,CH_L ;младшая часть 64-битного операнда
MOV EDX,CH_H ;старшая часть 64-битного операнда
M1: CLC ;очистка флага CF
RCL EAX,1 ;старший бит EAX в CF
RCL EDX,1 ;CF в младший бит EDX, старший бит EDX
LOOP M1 ;в CF
Команда RCR
(Циклический сдвиг операнда вправо через флаг переноса =
“Rotate operand through Carry flag Right”)
Синтаксис команды:
RCR <DEST>,<COUNT>
Семантика команды: операция циклического сдвига операнда вправо через флаг переноса CF.

Рис. 12.3.4. Схема работы команды RCR
Возможные варианты команды:
rcr mem/reg(8/16/32/64),count(cl/imm)
Алгоритм работы:
  • сдвиг всех битов операнда DEST вправо на один разряд, при этом младший бит операнда становится значением флага переноса CF;
  • одновременно старое значение флага переноса CF вдвигается в операнд слева и становится значением старшего бита операнда;
  • указанные выше два действия повторяются количество раз, равное значению операнда COUNT команды RCR. Количество битов может задаваться непосредственно в операнде COUNT или содержаться в регистре CL.
В случае команды RCR флаг OF представляет интерес, если сдвиг осуществляется на один разряд.
Применение: команда RCR используется для циклического сдвига разрядов операнда влево. Особенность этого сдвига в том, что он происходит с некоторой задержкой, так как очередной сдвигаемый бит оказывается на некоторое время вне операнда. В это время можно произвести его извлечение и (или) подмену. Другой важный момент заключается в том, что для счетчика сдвига микропроцессор использует только шесть младших разрядов операнда COUNT. Таким образом, значение, большее 63, микропроцессором не допускается (аппаратно это ограничение реализуется тем, что игнорируются значения всех битов счетчика, кроме первых шести). Обратите внимание на еще один интересный эффект, связанный с поведением флага OF. В операциях сдвига на один разряд по изменению этого флага можно судить о факте изменения знакового (старшего) разряда операнда:
  • OF=1, если текущее значение флага CF и выдвигаемого бита операнда слева различны;
  • OF=0, если текущее значение флага CF и выдвигаемого бита операнда слева совпадают:
Assembler
1
2
3
4
5
6
7
8
;подсчет числа единичных битов в операнде
OPERAND DW · · ·
XOR AL,AL ;счетчик единичных битов
MOV CX,16 ;размер операнда
CYCL: RCR OPERAND,1
JNC A ;переход,если очередной выдвинутый бит=0
INC AL ;увеличить счетчик единичных битов
A: LOOP CYCL
Записи
Запись – это упакованная структура, размер полей которой занимают не отдельные байты, а от одного до нескольких битов. Запись в языке ассемблер может иметь размер только кратный байту (байт, слово, двойное слово). Содержимое записи рассматривается как состоящее из нескольких частей, называемых полями записи. Каждое поле – это группа соседних битов. Поля должны быть прижатыми друг к другу, между ними не допускаются промежутки, не относящиеся к полям. Размер поля (число битов в нем) любой, но в сумме их размеры не должны превышать 8, 16, 32 и т.д. Сумма размеров всех полей записи называется размером записи. Если размер записи меньше или равен 8, то под запись компилятор отведет байт в памяти, при размере от 9 до 16 – отводится слово и так далее. Если поля занимают не всю ячейку, то они прижимаются к правому краю ячейки (к старшим битам), а левые (младшие) биты ячейки считаются не относящимися к записи. Поля получают имена, но обращаться к полю записи по имени нельзя.
Описание типа записи
Прежде чем использовать в программе записи, необходимо описать их тип с помощью директивы вида:
<имя типа записи> RECORD <поле> {, <поле>}
A B https://www.cyberforum.ru/cgi-bin/latex.cgi?\leftarrowимена полей
REC RECORD A:3, B:3=7 /// 0 7 
3 3 https://www.cyberforum.ru/cgi-bin/latex.cgi?\leftarrowразмеры полей
 Y M D https://www.cyberforum.ru/cgi-bin/latex.cgi?\leftarrowимена полей
DATE RECORD Y:7, M:4, D:5 0 0 0 
 7 4 5 https://www.cyberforum.ru/cgi-bin/latex.cgi?\leftarrowразмеры полей
При описании типа записи все ее поля перечисляются слева направо. Для каждого поля обязательно указывается имя и, через двоеточие, размер в битах. Имена полей должны отличаться от других имен, используемых в программе. При описании поля может быть указан знак «=» и значение этого поля по умолчанию. Это значение должно укладываться в размер поля (то есть, если поле n-битное, значение, которое там размещается, не должно быть более 2n). Если такое значение не указано, то значению поля по умолчанию присваивается 0. В этом отличие от структур и связано оно с тем, что оставить часть ячейки (поле) ничем не заполненным нельзя. Нулевыми будут и левые биты ячейки, не относящиеся к записи.
Описание типа записи носит информационный характер, по нему ассемблер ничего не заносит в машинные коды программы, поэтому его можно размещать в любом месте программы, но обязательно до описания переменных этого типа.
Описание переменных-записей
Переменные-записи называются просто записями. Для описания такой переменной в программу надо поместить директиву вида
имя_переменной имя_типа <нач_знач {, нач_знач}>
где нач_знач – это константное выражение, «?» или «пусто» (здесь уголки – не метасимволы, а явно указываемые символы).
Примеры:
Assembler
1
2
3
R1 REC <5,> ;R1: 0 5 7
R2 REC <,?> ;R2: 0 0 0
VIC DATE <45, 5, 9> ;VIC: 45 5 9
Смысл подобной директивы такой же, как и директивы, описывающей переменную-структуру: по ней отводится в памяти место (байт, слово или двойное слово) под запись, которой дается имя, а ее полям – начальные значения. Отличие проявляется лишь в том, что знак «?» означает нулевое начальное значение. Если же явно указано «пусто», то в качестве начального значения берется значение по умолчанию, заданное при описании типа данной переменной.
Допускается и следующее сокращение при задании начальных значений полей: если в качестве последних нач_знач указывается «пусто», то последние подряд идущие запятые можно опустить.
Например:
Assembler
1
2
D1 DATE <97,,> эквивалентно D1 DATE <97>
D2 DATE <,,> эквивалентно D2 DATE <>
(уголки опускать нельзя).
Как и в случае структур, одной директивой можно описать массив записей, для чего в правой части директивы указывается несколько операндов и/или конструкция повторения DUP. Например, по директиве
Assembler
1
X DATE 100 DUP (< >)
выделяется место сразу под 100 записей типа DATE, причем поля всех этих записей будут иметь одинаковые начальные значения – те, что указаны при описании этого типа.
Средства для работы с полями записей
Как видно, пока всё очень похоже на структуры. Однако дальше идут отличия. Дело в том, что на поля записи нельзя уже ссылаться с помощью конструкции вида <имя_записи>.<имя_поля> например, VIC.Y – ошибка. Это связано с тем, что такая конструкция должна обозначать не ячейку, а только часть ячейки, но части ячеек не адресуются. Поэтому такая конструкция не допускается в языке ассемблер. При работе с записями как едиными объектами проблем не возникает, так как запись в целом это байт, слово или двойное слово. Например, присвоение значений одной записи R1 другой записи R2 реализуется командами
Assembler
1
2
mov al,R1
mov R2,al
Для работы с полями записей используют оператор WIDTH
WIDTH <имя_поля_записи>
WIDTH <имя_записи_или_её_типа>
Если указано имя поля, то значением оператора является размер указанного поля в битах, а если указано имя записи или имя типа записи, тогда оператор выдает размер всей записи (сумму размеров всех ее полей).
Например:
WIDTH Y = 7
WIDTH REC = 6
12.4.4. Оператор MASK
MASK <имя_поля_записи>
MASK <имя_записи_или_её_типа>
Значением оператора является маска (байт, слово или двойное слово – в зависимости от размера записи), содержащая 1 в тех разрядах, которые принадлежат указанному полю или всем полям записи, и нули в остальных разрядах.
Например:
Assembler
1
2
3
4
MASK A = 00111000b
MASK B = 00000111b
MASK REC = 00111111b
MASK M = 0000000111100000b
Оператор MASK используется при выделении полей записей. Выгода от него в том, что не надо явно выписывать 1 и 0 для маски, за нас это делает компилятор. Например, проверить, содержит ли поле D записи VIC число 9, можно так:
Assembler
1
2
3
4
mov ax,VIC
and ax,mask D
cmp ax,9
je a1
Фактически, никакого выигрыша в этом нет, но запись mask D более наглядна чем 11111b или 1Fh.
Значение имени поля
Имени любого поля записи компилятор приписывает некоторое значение. Им является число, на которое надо сдвинуть это поле вправо, чтобы оно оказалось прижатым к правому краю ячейки. Например, значением имени D (из записи типа DATE) является число 0, имени M – число 5, имени Y – число 9.
Встречая имя поля записи в тексте программы, ассемблер заменяет его на это значение. Обычно это нужно в командах сдвига, в которых сдвигаем поля записей. Например, проверить, равно ли 5 поле M в записи VIC:
Assembler
1
2
3
4
5
6
mov ax,VIC ;ax: Y M В
and ax, mask M ;ax: 0 M 0
mov cl,M
shr ax,cl ;ax: 0 0 M
cmp ax,5 ;M=5?
je a1
Дополнительные возможности обработки записей
Для работы с записями добавлено две директивы SETFIELD и GETFIELD со следующим синтаксисом:
SETFIELD имя_поля_записи приемник, регистр_источник
GETFIELD имя_поля_записи регистр_приемник, источник
Работа директивы SETFIELD заключается в следующем. Местоположение записи определяется операндом приемник, который может представлять собой регистр или ячейку памяти. Операнд имя_поля_записи определяет элемент записи, с которым ведется работа (смещение элемента в записи относительно младшего разряда). Новое значение, в которое необходимо установить указанный элемент записи, должно содержаться в операнде регистр_источник. Обрабатывая данную директиву, транслятор генерирует последовательность команд, которые сдвигают содержимое операнда регистр_источник влево на количество разрядов, соответствующее расположению элемента в записи, выполняют операцию OR над операндами приемник и регистр_источник, результат помещается в операнд приемник. Действие директивы GETFIELD обратно действию SETFIELD. В качестве операнда источник может быть указан регистр или ячейка памяти. В регистр, указанный операндом регистр_приемник, помещается результат работы – значение элемента записи.

Миниатюры
Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник   Электронный учебник   Электронный учебник  

Электронный учебник   Электронный учебник  
Изображения
 
0
Закрытая тема Создать тему
Новые блоги и статьи
ИИ и человечность
kumehtar 21.07.2026
Забавно, что общаясь с ИИ, я замечаю, насколько он высказывается умно, и насколько верит в людей. Он умеет прощать. Он знает как отвечать не обесценивая опыт других людей, даже если сам не верит. Он. . .
Нейтральные знания ..., ... чистая наука. Пока что-то проходит модерацию на Хабре, стоит развить мысль ...
Hrethgir 20.07.2026
К таким радикальным взглядам я конечно в той публикации не приходил, но чтобы скоротать вечер, решил углубиться немного. 1. Почему показания термометра заряжены целью? Цель заложена в самом. . .
Установка нескольких штампов электронной подписи в строго определенных местах файла docx
ВладимирСамохин 19.07.2026
(В!) Работа с Электронной подписью - это неотъемлемая часть современного документооборота. Но что делать, если нужно поставить несколько штампов электронной подписи в строго определенных местах. . .
сукцессия 35. Научная статья о проделанной работе
anaschu 19.07.2026
Написал в формате латекс и пдф
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ По ссылке 403. Не очень информативно такую ссылку постить. Запись от Usaga размещена Сегодня в 06:46 . . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru