Вычитание упакованных BCD-чисел 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Вычитание упакованных BCD-чисел



Аналогично сложению, микропроцессор рассматривает упакованные BCD-числа как двоичные и, соответственно, выполняет вычитание BCD-чисел как двоичных.

Пример 14.

Вычитание упакованных BCD-чисел

Выполним вычитание 67-75. Так как микропроцессорвыполняет вычитание способом сложения, то и мы последуемэтому: 67 = 0110 0111 + -75 = 1011 0101 = -8 = 0001 1100 = 28???

Как видим, результат равен 28 в десятичной системе счисления, что является абсурдом. В двоично-десятичном коде результат должен быть равен 0000 1000 (или 8 в десятичной системе счисления).

При программировании вычитания упакованных BCD-чисел программист, как и при вычитании неупакованных BCD-чисел, должен сам осуществлять контроль за знаком. Это делается с помощью флага cf, который фиксирует заем из старших разрядов.
Само вычитание BCD-чисел осуществляется простой командой вычитания sub или sbb. Коррекция результата осуществляется командой das:

das (Decimal Adjust for Substraction) — коррекция результата вычитания для представления в десятичном виде.
Команда das преобразует содержимое регистра al в две упакованные десятичные цифры по алгоритму, приведенному в описании команды das.

Логические команды

Логические команды

В системе команд микропроцессора есть следующий набор команд, поддерживающих работу с логическими данными:

and операнд_1,операнд_2 — операция логического умножения.
Команда выполняет поразрядно логическую операцию И (конъюнкцию) над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

or операнд_1,операнд_2 — операция логического сложения.
Команда выполняет поразрядно логическую операцию ИЛИ (дизъюнкцию) над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

xor операнд_1,операнд_2 — операция логического исключающего сложения.
Команда выполняет поразрядно логическую операцию исключающего ИЛИ над битами операндов операнд_1 и операнд_2. Результат записывается на место операнд_1.

test операнд_1,операнд_2 — операция “проверить” (способом логического умножения).
Команда выполняет поразрядно логическую операцию И над битами операндов операнд_1 и операнд_2. Состояние операндов остается прежним, изменяются только флаги zf, sf, и pf, что дает возможность анализировать состояние отдельных битов операнда без изменения их состояния.

not операнд — операция логического отрицания.
Команда выполняет поразрядное инвертирование (замену значения на обратное) каждого бита операнда. Результат записывается на место операнда.

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

  • Для установки определенных разрядов (бит) в 1 применяется команда
    or операнд_1,операнд_2.
    В этой команде операнд_2, выполняющий роль маски, должен содержать единичные биты на месте тех разрядов, которые должны быть установлены в 1 в операнд_1.
or eax,10b;установить 1-й бит в регистре eax
  • Для сброса определенных разрядов (бит) в 0 применяется команда
    and операнд_1,операнд_2.
    В этой команде операнд_2, выполняющий роль маски, должен содержать нулевые биты на месте тех разрядов, которые должны быть установлены в 0 в операнд_1.
and eax,fffffffdh;сбросить в 0 1-й бит в регистре eax
  • Команда xor операнд_1,операнд_2 применяется:
    • для выяснения того, какие биты в операнд_1 и операнд_2 различаются;
    • для инвертирования состояния заданных бит в операнд_1.
xor eax,10b;инвертировать 1-й бит в регистре eax jz mes;переход, если 1-й бит в al был единичным

· Интересующие нас биты маски (операнд_2) при выполнении команды xor должны быть единичными, остальные — нулевыми.

  • Для проверки состояния заданных бит применяется команда
    test операнд_1,операнд_2 (проверить операнд_1).
    Проверяемые биты операнд_1 в маске (операнд_2) должны иметь единичное значение. Алгоритм работы команды test подобен алгоритму команды and, но он не меняет значения операнд_1.
    Результатом команды является установка значения флага нуля zf:
    • если zf = 0, то в результате логического умножения получился нулевой результат, то есть один единичный бит маски, который не совпал с соответствующим единичным битом операнд_1;
    • если zf = 1, то в результате логического умножения получился ненулевой результат, то есть хотя бы один единичный бит маски совпал с соответствующим единичным битом операнд_1.
test eax,00000010h jz m1;переход, если 4-й бит равен 1

Как видно из примера, для реакции на результат команды test целесообразно использовать команду перехода jnz метка (Jump if Not Zero) — переход, если флаг нуля zf ненулевой, или команду с обратным действием — jz метка (Jump if Zero) — переход, если флаг нуля zf = 0.

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

bsf операнд_1,операнд_2 (Bit Scaning Forward) - сканирование битов вперед.
Команда просматривает (сканирует) биты операнд_2 от младшего к старшему (от бита 0 до старшего бита) в поисках первого бита, установленного в 1. Если таковой обнаруживается, в операнд_1 заносится номер этого бита в виде целочисленного значения. Если все биты операнд_2 равны 0, то флаг нуля zf устанавливается в 1, в противном случае флаг zf сбрасывается в 0.

mov al,02h bsf bx,al;bx=1 jz m1;переход, если al=00h...

bsr операнд_1,операнд_2 (Bit Scaning Reset) — сканирование битов в обратном порядке.
Команда просматривает (сканирует) биты операнд_2 от старшего к младшему (от старшего бита к биту 0) в поисках первого бита, установленного в 1. Если таковой обнаруживается, в операнд_1 заносится номер этого бита в виде целочисленного значения.
При этом важно, что позиция первого единичного бита слева отсчитывается все равно относительно бита 0. Если все биты операнд_2 равны 0, то флаг нуля zf устанавливается в 1, в противном случае флаг zf сбрасывается в 0.

Листинг 1 демонстрирует пример применения команд bsr и bsf. Введите код и исследуйте работу программы в отладчике (в частности, обратите внимание на то, как меняется содержимое регистра bx после команд bsf и bsr).

Листинг 1 Сканирование битов;prg_9_1.asmmasmmodel smallstack 256.data;сегмент данных.code;сегмент кодаmain:;точка входа в программу mov ax,@data mov ds,ax;....486;это обязательно xor ax,ax mov al,02h bsf bx,ax;bx=1 jz m1;переход, если al=00h bsr bx,axm1:;... mov ax,4c00h;стандартный выход int 21hend main

В последних моделях микропроцессоров Intel в группе логических команд появилось еще несколько команд, которые позволяют осуществить доступ к одному конкретному биту операнда. Операнд может находиться как в памяти, так и в регистре общего назначения. Положение бита задается смещением бита относительно младшего бита операнда. Значение смещения может задаваться как в виде непосредственного значения, так и содержаться в регистре общего назначения. В качестве значения смещения вы можете использовать результаты работы команд bsr и bsf. Все команды присваивают значение выбранного бита флагу cf.

bt операнд,смещение_бита (Bit Test) — проверка бита.
Команда переносит значение бита в флаг cf.

bt ax,5;проверить значение бита 5 jnc m1;переход, если бит = 0

bts операнд,смещение_бита (Bit Test and Set) — проверка и установка бита.
Команда переносит значение бита в флаг cf и затем устанавливает проверяемый бит в 1.

mov ax,10 bts pole,ax;проверить и установить 10-й бит в pole jсm1;переход, если проверяемый бит был равен 1

btr операнд,смещение_бита (Bit Test and Reset) — проверка и сброс бита.
Команда переносит значение бита в флаг cf и затем устанавливает этот бит в 0.

btc операнд,смещение_бита (Bit Test and Convert) — проверка и инвертирование бита.
Команда переносит значение бита в флаг cf и затем инвертирует значение этого бита.

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

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

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

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

Количество сдвигаемых разрядов — счетчик_сдвигов — располагается, как видите, на месте второго операнда и может задаваться двумя способами:

  • статически, что предполагает задание фиксированного значения с помощью непосредственного операнда;
  • динамически, что означает занесение значения счетчика сдвигов в регистр cl перед выполнением команды сдвига.

Исходя из размерности регистра cl, понятно, что значение счетчика сдвигов может лежать в диапазоне от 0 до 255. Но на самом деле это не совсем так.
В целях оптимизации микропроцессор воспринимает только значение пяти младших битов счетчика, то есть значение лежит в диапазоне от 0 до 31.
В последних моделях микропроцессора, в том числе и в микропроцессоре Pentium, есть дополнительные команды, позволяющие делать 64-разрядные сдвиги. Мы их рассмотрим чуть позже.

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

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

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

Команды линейного сдвига

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

  • очередной “выдвигаемый” бит устанавливает флаг cf;
  • бит, вводимый в операнд с другого конца, имеет значение 0;
  • при сдвиге очередного бита он переходит во флаг cf, при этом значение предыдущего сдвинутого бита теряется!

Команды линейного сдвига делятся на два подтипа:

  • команды логического линейного сдвига;
  • команды арифметического линейного сдвига.

К командам логического линейного сдвига относятся следующие:

shl операнд,счетчик_сдвигов (Shift Logical Left) - логический сдвиг влево.
Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули;

shr операнд,счетчик_сдвигов (Shift Logical Right) — логический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество битов, определяемое значением счетчик_сдвигов. Слева (в позицию старшего, знакового бита) вписываются нули. На рис. 1 показан принцип работы этих команд.

Рис. 1. Схема работы команд линейного логического сдвига

Ниже показан фрагмент программы, который выполняет преобразование двух неупакованных BCD-чисел в слове памяти bcd_dig в упакованное BCD-число в регистре al.

...bcd_dig dw 0905h;описание неупакованного BCD-числа 95... mov ax,bcd_dig;пересылка shl ah,4;сдвиг влево add al,ah;сложение для получения результата: al=95h

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

sal операнд,счетчик_сдвигов (Shift Arithmetic Left) — арифметический сдвиг влево.
Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули. Команда sal не сохраняет знака, но устанавливает флаг cf в случае смены знака очередным выдвигаемым битом. В остальном команда sal полностью аналогична команде shl;

sar операнд,счетчик_сдвигов (Shift Arithmetic Right) — арифметический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество битов, определяемое значением счетчик_сдвигов. Слева в операнд вписываются нули. Команда sar сохраняет знак, восстанавливая его после сдвига каждого очередного бита.
На рис. 2 показан принцип работы команд линейного арифметического сдвига.

Рис. 2. Схема работы команд линейного арифметического сдвига

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

К командам циклического сдвига относятся команды, сохраняющие значения сдвигаемых бит. Есть два типа команд циклического сдвига:

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

К командам простого циклического сдвига относятся:

rol операнд,счетчик_сдвигов (Rotate Left) — циклический сдвиг влево.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа.

ror операнд,счетчик_сдвигов (Rotate Right) — циклический сдвиг вправо.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые вправо биты записываются в тот же операнд слева.

Рис. 3. Схема работы команд простого циклического сдвига

Как видно из рис. 3, команды простого циклического сдвига в процессе своей работы осуществляют одно полезное действие, а именно: циклически сдвигаемый бит не только вдвигается в операнд с другого конца, но и одновременно его значение становиться значением флага cf.
К примеру, для того чтобы обменять содержимое двух половинок регистра eax, достаточно выполнить следующую последовательность команд:

... mov eax,ffff0000h mov cl,16 rol eax,cl

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

К командам циклического сдвига через флаг переноса cf относятся следующие:

rcl операнд,счетчик_сдвигов (Rotate through Carry Left) — циклический сдвиг влево через перенос.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.

rcr операнд,счетчик_сдвигов (Rotate through Carry Right) — циклический сдвиг вправо через перенос.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.

Рис. 4. Команды циклического сдвига через флаг переноса cf

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



Поделиться:


Последнее изменение этой страницы: 2017-02-05; просмотров: 557; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 54.243.2.41 (0.054 с.)