assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 46
Текст из файла (страница 46)
9.2. Схема работы команд линейного логического сдвигаНиже показан фрагмент программы, выполняющей преобразование двух неупакованных BCD-чисел в слове памяти bcd_dig в упакованное BCD-число в регистре AL.bcd_dig dw0905hmov ax,bcd_digshl ah,4add a l , a hописание неупакованного BCD-числа 95пересылкасдвиг влевосложение для получения р е з у л ь т а т а : al=95hКоманды арифметического линейного сдвига отличаются от команд логическогосдвига тем, что они особым образом работают со знаковым разрядом операнда:ii 5а1операнд,счетчик_сдвигов — арифметический сдвиг влево (Shift Arithmetic Left).Содержимое операнда сдвигается влево на количество битов, определяемоезначением счетчик_сдвигов.
Справа (в позицию младшего бита) вписываютсянули. Команда SAL не сохраняет знака, но устанавливает флаг OF в случае сменызнака очередным выдвигаемым битом. В остальном команда SAL полностью аналогична команде SHL;я sar операнд,счетчик_сдвигов — арифметический сдвиг вправо (Shift ArithmeticRight). Содержимое операнда сдвигается вправо на количество битов, определяемое значением счетчик_сдвигов.
Слева в операнд вписываются нули. Команда SAR сохраняет знак, восстанавливая его после сдвига каждого очередного бита.Рисунок 9.3 иллюстрирует принцип работы команд линейного арифметического сдвига.Команды сдвига201Сдвиг влево арифметический salУVVУVVV7654321ч«0Флаг cfСдвиг вправо арифметический sar43210Флаг cfРис. 9.3.
Схема работы команд линейного арифметического сдвигаКоманды арифметического сдвига позволяют выполнить «быстрое» умножение и деление операнда на степени двойки. Посмотрите на двоичное представление чисел 75 и 150:75 01001011150 10010110Второе число является сдвинутым влево на один разряд первым числом. Еслиу вас еще есть сомнения, проделайте несколько умножений на 2, 4, 8 и т.
д.Аналогичная ситуация — с операцией деления. Сдвигая вправо операнд, мы,фактически, осуществляем операцию деления на степени двойки 2, 4, 8 и т. д.Преимущество этих команд по сравнению с командами умножения и деления —в скорости их исполнения процессором, что может пригодиться при оптимизациипрограммы.Циклический сдвигК командам циклического сдвига относятся команды, сохраняющие значения сдвигаемых битов. Есть два типа команд циклического сдвига:' - команды простого циклического сдвига (рис. 9.4);;- команды циклического сдвига через флаг переноса CF (рис. 9.5).Далее перечислены команды простого циклического сдвига:•'• rol операнд,счетчик_сдвигов — циклический сдвиг влево (Rotate Left). Содержимое операнда сдвигается влево на количество битов, определяемое операндомсчетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операндсправа.ш гог операнд,счетчик_сдвитов — циклический сдвиг вправо (Rotate Right).
Содержимое операнда сдвигается вправо на количество битов, определяемое операндом счетчик_сдвигов. Сдвигаемые вправо биты записываются в тот же операндслева.202Глава 9. Логические команды и команды сдвигаСдвиг влево циклический го!'VVУVУV7654321Г~^V-,0Флаг cfСдвиг вправо циклический гог,s//УVУУУ765432V1*<_,0Флаг cfРис. 9.4. Схема работы команд простого циклического сдвигаСдвиг влево циклический rcl-УVVУУV7654321VV21VV0Флаг cfСдвиг вправо циклический гсгУVVV76б4V3^~10— rfФлаг cfРис. 9.5. Схема работы команд циклического сдвига через флаг переноса CFКак видно из рис.
9.4, команды простого циклического сдвига в процессе своейработы осуществляют одно полезное действие: циклически сдвигаемый бит не только вдвигается в операнд с другого конца, но и одновременно его значение становится значением флага CF. К примеру, для того чтобы обменять содержимое двухполовинок регистра ЕАХ, достаточно выполнить следующую последовательностькоманд:mov eax,ffffOOOOhmov с I,16rot eax.clКоманды циклического сдвига через флаг переноса CF отличаются от командпростого циклического сдвига тем, что сдвигаемый бит не сразу попадает в операнд с другого его конца, а сначала записывается во флаг переноса CF.
Лишь следу-Команды сдвига203ющее исполнение данной команды сдвига (при условии, что она выполняетсяв цикле) приводит к помещению выдвинутого ранее бита в другой конец операнда(рис. 9.5). Команды циклического сдвига через флаг переноса CF перечисленыдалее:Л rcl операнд,счетчик_сдвигов — циклический сдвиг влево через перенос (Rotatethrough Carry Left). Содержимое операнда сдвигается влево на количество битов, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередностановятся значением флага переноса CF;ii rcr операнд,счетчик_сдвигов — циклический сдвиг вправо через перенос (Rotatethrough Carry Right).
Содержимое операнда сдвигается вправо на количествобитов, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередностановятся значением флага переноса CF.Из рис. 9.5 видно, что при сдвиге через флаг переноса появляется промежуточный элемент, с помощью которого можно производить подмену циклически сдвигаемых битов, в частности, выполнять рассогласование битовых последовательностей.Под рассогласованием битовой последовательности здесь и далее подразумевается действие, которое позволяет некоторым образом локализовать и извлечь нужные участки этой последовательности и записать их в другое место.
Например,рассмотрим, как переписать в регистр ВХ старшую половину регистра ЕАХ с одновременным ее обнулением в регистре ЕАХ:ml:mov cx,16clcrcl e a x . lrcl b x , 1loopmlrol еах,16;кол-во сдвигов для еах;сброс флага cf в 0;сдвиг крайнего левого бита из еах в cfперемещение бита из cf справа в Ьх;цикл 16 развосстановить правую часть еахКоманды простого циклического сдвига можно использовать для операций другого рода.
К примеру, подсчитаем количество единичных битов в регистре ЕАХ:хогmovcycl:гогjncdx.dxсх,32еах,1not_oneinc dxnot_one:loopcycl;очистка dx для подсчета единичных битов;число циклов подсчета;метка циклациклический сдвиг вправо на 1 бит;переход, если очередной бит в cf;не равен единицеувеличение счетчика цикла;переход на метку cycl, если;значение в сх не равно 0Этот фрагмент не требует особых пояснений, единственное, что нужно помнить, — особенности работы команды цикла ШОР (глава 10).
Команда ШОР сравнивает значение регистра ЕСХ/СХ с нулем и, если оно не равно нулю, выполняетуменьшение ЕСХ/СХ на единицу и передает управление на метку в программе, указанную в этой команде в качестве операнда.Дополнительные команды сдвигаСистема команд моделей микропроцессоров Intel, начиная с 80386, содержит дополнительные команды сдвига, расширяющие рассмотренные нами ранее возможности. Это — команды сдвига двойной точности:204Глава 9.
Логические команды и команды сдвигаii shld операнд_1,операнд_2,счетчик_сдвигов — сдвиг влево двойной точности. Команда сдвигает биты первого операнда влево и заполняет его справа значениями битов, вытесняемых из второго операнда, согласно схеме на рис. 9.6. Количество сдвигаемых битов определяется значением счетчика сдвигов, котороеможет лежать в диапазоне 0...31. Это значение может задаваться непосредственнов третьем операнде или содержаться в регистре CL. Значение второго операндане меняется;I,<- 1 — ' •*- I — "-shld операнд_1, операнд_2, рчетчик_сдвигов,— ,„— * .{L *«операнд_1210операнд_2210Рис. 9.6.
Схема работы команды SHLDshrd операнд_1,операнд_2,счетчик_сдвигов — сдвиг вправо двойной точности. Команда сдвигает биты первого операнда вправо и заполняет его слева значениями битов, вытесняемых из второго операнда, согласно схеме на рис. 9.7. Количество сдвигаемых битов определяется значением счетчика сдвигов, котороеможет лежать в диапазоне 0...31. Это значение может задаваться непосредственнов третьем операнде или содержаться в регистре CL. Значение второго операндане меняется.shrd операнд_1, операнд_2, счетчик_сдвигов210операнд_2- 21Ооперанд_1Флаг ofРис. 9.7.
Схема работы команды SHRDКак мы отметили, команды SHLD и SHRD осуществляют сдвиги на величину до32 разрядов, но за счет особенностей задания операндов и алгоритма работы этикоманды можно использовать для работы с полями длиной до 64 битов. Например, рассмотрим, как можно осуществить сдвиг влево на 16 битов поля из 64 битов..datapole_l dd 0b21187f5hpole_h dd 45ff6711h.codemov cl,16;загрузка счетчика сдвигов в clmov eax,pole_hshldpole_l ,eax,clshl pole_h,cl;pole_l=87f50000h;pole_h=6711b211hРассмотрим еще некоторые наиболее типичные примеры применения этих команд.
Отметим следующий момент. Рассмотренные далее действия, конечно,.можноПримеры работы с битовыми строками205выполнить и множеством других способов, но эти являются самыми быстрыми.Если ваши программы должны работать максимально быстро, то есть смысл потратить время на разбор этих примеров.Примеры работы с битовыми строкамиРассогласование битовых строкНаглядный пример рассогласования последовательностей битов — преобразование неупакованного BCD-числа в упакованное BCD-число.
Один из вариантовтакого преобразования был рассмотрен нами ранее при обсуждении команды линейного сдвига SHL Попробуем выполнить подобное преобразование с использованием команд сдвига двойной точности (листинг 9.2). В общем случае длина числа может быть произвольной, но при этом нужно учитывать ограничения, которыенакладываются используемыми ресурсами процессора. Ограничения связаны в основном с тем, что центральное место в преобразовании занимает регистр ЕАХ, поэтому, если преобразуемое число имеет размер более четырех байтов, то его придется делить на части. Но это уже чисто алгоритмическая задача, поэтому в нашемслучае предполагается, что неупакованное BCD-число имеет длину 4 байта.Листинг 9.2.