Как сложить 2 двоичных числа в ассемблере
Перейти к содержимому

Как сложить 2 двоичных числа в ассемблере

  • автор:

Как сложить 2 двоичных числа в ассемблере

Иллюстрированный самоучитель по задачам и примерам Assembler

Прежде чем программировать, запишите программу в псевдокодах.

Д. Ван Тассел

Сложение чисел размером 1 байт без учета знака

Программа учитывает возможное переполнение результата. Сложение двоичных чисел большей размерности (2/4 байта) выполняется аналогично. Для этого необходимо заменить директивы DB на DW/DD и регистр AL на АХ/ЕАХ.

Сложение чисел размером N байт без учета знака

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

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

Как сложить 2 двоичных числа в ассемблере

7.1. Сложение и вычитание.

7.1.1. ADD – команда для сложения двух чисел. Она работает как с числами со знаком, так и без знака.

ADD Приемник , Источник

Логика работы команды:

<Приемник> = <Приемник> + <Источник>

Возможные сочетания операндов для этой команды аналогичны команде MOV .

По сути дела, это – команда сложения с присвоением, аналогичная принятой в языке C / C ++:

Приемник += Источник;

Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.

После выполнения команды изменяются флаги, по которым можно определить характеристики результата:

  1. Флаг CF устанавливается, если при сложении произошёл перенос из старшего разряда. Для беззнаковых чисел это будет означать, что произошло переполнение и результат получился некорректным.
  2. Флаг OF обозначает переполнение для чисел со знаком.
  3. Флаг SF равен знаковому биту результата (естественно, для чисел со знаком, а для беззнаковых он равен старшему биту и особо смысла не имеет).
  4. Флаг ZF устанавливается, если результат равен 0.
  5. Флаг PF — признак чётности, равен 1, если результат содержит нечётное число единиц.

add ax ,5 ; AX = AX + 5

add dx,cx ;DX = DX + CX

add dx,cl ;Ошибка: разный размер операндов.

7.1.2. SUB — команда для вычитания одного числа из другого. Она работает как с числами со знаком, так и без знака.

SUB Приемник , Источник

Логика работы команды:

<Приемник> = <Приемник> — <Источник>

Возможные сочетания операндов для этой команды аналогичны команде MOV .

По сути дела, это – команда вычитания с присвоением, аналогичная принятой в языке C / C ++:

Приемник -= Источник;

Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.

На самом деле вычитание в процессоре реализовано с помощью сложения. Процессор меняет знак второго операнда на противоположный, а затем складывает два числа.

sub ax ,13 ; AX = AX — 13

sub ax , bx ; AX = AX + BX

sub b x,cl ;Ошибка: разный размер операндов.

7.1.3. Инкремент и декремент. Очень часто в программах используется операция прибавления или вычитания единицы. Прибавление единицы называется инкрементом, а вычитание — декрементом. Для этих операций существуют специальные команды процессора: INC и DEC. Эти команды не изменяют значение флага CF.

Эти команды содержит один операнд и имеет следующий синтаксис:

INC Операнд

DEC Операнд

Логика работы команд:

INC : <Операнд> = < Операнд > + 1

DEC : <Операнд> = < Операнд > — 1

В качестве инкремента допустимы регистры и память: reg , mem .

inc ax ; AX = AX + 1

dec ax ; AX = AX — 1

7.1.4. NEG – команда для изменения знака операнда.

NEG Операнд

Логика работы команды:

<Операнд> = – < Операнд >

В качестве декремента допустимы регистры и память: reg , mem .

7.2. Сложение и вычитание с переносом.

В системе команд процессоров x86 имеются специальные команды сложения и вычитания с учётом флага переноса (CF). Для сложения с учётом переноса предназначена команда ADC, а для вычитания — SBB. В общем, эти команды работают почти так же, как ADD и SUB, единственное отличие в том, что к младшему разряду первого операнда прибавляется или вычитается дополнительно значение флага CF.

Они позволяют выполнять сложение и вычитание многобайтных целых чисел, длина которых больше, чем разрядность регистров процессора (в нашем случае 16 бит). Принцип программирования таких операций очень прост — длинные числа складываются (вычитаются) по частям. Младшие разряды складываются(вычитаются) с помощью обычных команд ADD и SUB, а затем последовательно складываются(вычитаются) более старшие части с помощью команд ADC и SBB. Так как эти команды учитывают перенос из старшего разряда, то мы можем быть уверены, что ни один бит не потеряется. Этот способ похож на сложение(вычитание) десятичных чисел в столбик.

На следующем рисунке показано сложение двух двоичных чисел командой ADD:

При сложении происходит перенос из 7-го разряда в 8-й, как раз на границе между байтами. Если мы будем складывать эти числа по частям командой ADD, то перенесённый бит потеряется и в результате мы получим ошибку. К счастью, перенос из старшего разряда всегда сохраняется в флаге CF. Чтобы прибавить этот перенесённый бит, достаточно применить команду ADC:

Как сложить 2 двоичных числа в ассемблере

На этом шаге мы познакомимся с правилами выполнения действий с двоичными числами.

Так как компьютер может различить только нулевое и единичное состояние бита, то он работает в системе счисления с основанием 2 или в двоичной системе . Бит получил свое название от английского Binary digit ( двоичная цифра ) .

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

Самая правая цифра имеет весовое значение 1, следующая цифра влево — 2, следующая — 4 и т.д. Общая сумма для восьми единичных битов в данном случае составит 255 (1+2+4+8+16+32+64+128=255).

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

Проиллюстрируем использование этих правил на конкретном примере.

Пример: сложить числа 65 и 42, представленные в двоичной системе счисления. В десятичной системе счисления все осуществляется достаточно просто: 65+42=107.

Для сложения этих чисел в двоичной системе счисления нужно сначала перевести их в эту систему:

Рис.1. Алгоритм перевода числа из десятичной в двоичную систему счисления

Таким образом, получаем: 65 10 = 01000001 2 . Обратите внимание на то, что ведущий ноль в двоичном представлении числа добавлен для дополнения двоичного представления до восьми бит.

Аналогично: 42 10 = 00101010 2 . Выполним сложение этих чисел:

Можно убедиться, что 01101011 2 =107 10 :

Мы рассмотрели сложение чисел в компьютере. А как же осуществляется вычитание? Для выполнения операции вычитания оно заменяется сложением, а в качестве второго слогаемого берется противоположное число. Например, пусть надо выполнить вычитание: 65 — 42. Заменим его сложением: 65 + (-42). Но как получить соответствующее двоичное отрицательное число? Этот вопрос мы сейчас рассмотрим.

Приведем пример использования рассмотренного алгоритма.

Пример 1. Получить двоичное представление числа -65. Напомним, что 65 10 = 01000001 2 . Инвертируем биты: 10111110 . К полученному числу прибавим 1: 10111110+1=10111111 . Убедимся в правильности представления. Сумма +65 и -65 должна составить нуль:

Все восемь бит имеют нулевое значение. Пока будем считать, что полученная единица, перенесенная влево, потеряна.

Это правило позволяет выполнять вычитание чисел в двоичной системе счисления: вычитание заменяется сложением и в качестве второго слагаемого берется отрицательное число.

Пример 2. Вычесть из 65 число 42. Двоичное представление для 42 — это 00101010, а для -42 двоичное представление будет следующим — 11010110:

Пример 3. Какое значение необходимо прибавить к двоичному числу 00000001, чтобы получить число 00000000? В терминах десятичного счисления ответом будет число -1. Для двоичного счисления это число 11111111:

В заключение приведем фрагмент уменьшающегося ряда чисел в двоичном представлении:

На следующем шаге мы познакомимся с шестнадцатеричным представлением чисел.

Как сложить 2 двоичных числа в ассемблере

Ассемблер. Сложение шестнадцатиричных чисел\вычитание двоичных
Program RaznostMassivov; const N=7; var a1:array of longint; a2:array of longint; .

Сложение двоичных чисел.
Попытался сложить двоичные числа �� осознаю что ето бред,кто направит на путь истинный?: .

сложение двоичных чисел
Господа программисты! У меня проблема которую надо срочно решить! Буду очень благодарен за помощь.

Сложение двоичных чисел
можете помочь исправить ошибки и сделать эту задачу с вычитанием сложение: program summa2;.

Сообщение от grobnar

Нуля не хватает

CF=PF=1, это значит
1.) CF=1 следовательно один из битов был перенесен(1010000001010, выделенный жирным).
2.) PF=1 следовательно, число единичных битов четно.

Добавлено через 7 минут

Сообщение от grobnar

Здесь не правильно.

При AH=1010, AL=1010
Так как 10>9,то
AL увеличиваем на 6:
AL=1010+110 = 10000
Очищаем старший полубайт AL, остается 0000
Увеличиваем AH на 1: AH=1011
AF=1 CF=1
Итак, в итоге должно получиться
AH=1011, AL=0000

Добавлено через 1 минуту
Материал про AAA

(Ascii Adjust after Addition)
ASCII-коррекция после сложения

Схема команды: aaa
Назначение: корректировка неупакованного результата сложения двух одноразрядных неупакованных BCD-чисел.
Синтаксис
Алгоритм работы:

проанализировать значение младшего полубайта регистра al и значение флага af;
если (значение младшего полубайта регистра al >9) или (AF=1), то выполнить следующие действия:
увеличить значение al на 6;
очистить старший полубайт регистра al;
увеличить значение ah на 1;
установить флаги: af = 1, cf = 1,
иначе сбросить флаги af = 0 и cf = 0.
Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? ? ? r ? r
Применение:
Обычно команда aaa используется после сложения каждого разряда распакованных BCD-чисел командой add. Каждая цифра неупакованного BCD-числа занимает младший полубайт байта. Если результат сложения двух одноразрядных BCD-чисел больше 9, то число в младшем полубайте результата не есть BCD-число. Поэтому результат нужно корректировать командой aaa. Эта команда позволяет сформировать правильное BCD-число в младшем полубайте и запомнить единицу переноса в старший разряд путем увеличения содержимого регистра ah на 1.
К примеру, сложить два неупакованных BCD-числа: 08 + 05:
mov ah,08h ;ah=08h
mov al,05h ;al=05h
add al,ah ;al=al+ah=05h+08h=0dh — не BCD-число
xor ah,ah ;ah=0
aaa ;ah=01h,al=03h — результат скорректирован

Сообщение от grobnar

(Ascii Adjust after Multiply)
ASCII-коррекция после умножения

Схема команды: aam
Назначение:
корректировка результата умножения двух неупакованных BCD-чисел;
преобразование двоичного числа меньшего 63h (9910) в его неупакованный BCD-эквивалент.
Синтаксис
Алгоритм работы:
разделить значение регистра al на 10;
записать частное в регистр ah, остаток — в регистр al.
Состояние флагов после выполнения команды:
11 07 06 04 02 00
OF SF ZF AF PF CF
? r r r r ?
Применение:
Команду aam используют для коррекции результата умножения двух неупакованных BCD-чисел. Специальной команды умножения BCD-чисел нет. Поэтому BCD-числа умножаются поразрядно, как обычные двоичные числа, командой mul. Максимальное число, которое получается при таком умножении, — это 9*9=8110=5116. Отсюда понятно, что значения, для которых командой aam можно получить их двузначный BCD-эквивалент в регистре ax, находятся в дипазоне от 00h до 51h. Эту команду можно применять и для преобразования двоичного числа из регистра ax (в диапазоне от 0 до 63h) в его десятичный эквивалент(соответственно, из диапазона от 0 до 9910).
Пример 1. Умножить десятичное число 8 на 9. Подготовить результат к выводу на экран.
mov ah,08h ;ah=08h
mov al,09h ;al= 09h
mul ah ;al=48h — двоичный эквивалент 72
aam ;ah=07h,al=02h
or ax,3030h ;ax=3732h — ASCII-представление числа 72
Пример 2. Преобразовать двоичное число 60h в эквивалентное десятичное число.
;поместим число 60h в регистр ax
mov ax,60h ;ax=60h
aаm ;ax=0906h — получили десятичный эквивалент числа 60h
or ax,3030h ;символьный эквивалент, можно выводить на экран

Иллюстрированный самоучитель по задачам и примерам Assembler

Прежде чем программировать, запишите программу в псевдокодах.

Д. Ван Тассел

Сложение чисел размером 1 байт без учета знака

Программа учитывает возможное переполнение результата. Сложение двоичных чисел большей размерности (2/4 байта) выполняется аналогично. Для этого необходимо заменить директивы DB на DW/DD и регистр AL на АХ/ЕАХ.

Сложение чисел размером N байт без учета знака

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

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

Арифметические операции над двоично-десятичными числами

Арифметические действия над неупакованными BCD-числами

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

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

Назначение этих команд — в корректировке результата работы обычных арифметических команд для случаев когда операнды в них являются BCD-числами.

В случае вычитания в примере 10 видно, что полученный результат нужно корректировать. Для коррекции операции сложения двух однозначных неупакованных BCD-чисел в системе команд микропроцессора существует специальная команда

aaa (ASCII Adjust for Addition) — коррекция результата сложения для представления в символьном виде.

  • к содержимому младшей тетрады al (но не к содержимому всего регистра!) прибавляется 6, тем самым значение десятичного результата корректируется в правильную сторону;
  • флаг cf устанавливается в 1, тем самым фиксируется перенос в старший разряд, для того чтобы его можно было учесть в последующих действиях.

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

aas (ASCII Adjust for Substraction) — коррекция результата вычитания для представления в символьном виде.

  1. из содержимого младшей тетрады регистра al (заметьте — не из содержимого всего регистра) вычитает 6;
  2. обнуляет старшую тетраду регистра al;
  3. устанавливает флаг cf в 1, тем самым фиксируя воображаемый заем из старшего разряда.

Умножение неупакованных BCD-чисел

Для того чтобы умножать числа произвольной размерности, нужно реализовать процесс умножения самостоятельно, взяв за основу некоторый алгоритм умножения, например “в столбик”.

aam (ASCII Adjust for Multiplication) — коррекция результата умножения для представления в символьном виде.

В листинге 10 приведен пример умножения BCD-числа произвольной размерности на однозначное BCD-число. Данную программу можно легко модифицировать для умножения BCD-чисел произвольной длины. Для этого достаточно представить алгоритм умножения “в столбик”. Листинг 10 можно использовать для получения частичных произведений в этом алгоритме. После их сложения со сдвигом получиться искомый результат.

Перед окончанием обсуждения команды aam необходимо отметить еще один вариант ее применения. Эту команду можно применять для преобразования двоичного числа в регистре al в неупакованное BCD-число, которое будет размещено в регистре ax: старшая цифра результата в ah, младшая — в al. Понятно, что двоичное число должно быть в диапазоне 0. 99.

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

aad (ASCII Adjust for Division) — коррекция деления для представления в символьном виде.

Деление неупакованных BCD-чисел иллюстрируется листингом 11. Аналогично aam, команде aad можно найти и другое применение — использовать ее для перевода неупакованных BCD-чисел из диапазона 0. 99 в их двоичный эквивалент.

Для деления чисел большей разрядности, так же как и в случае умножения, нужно реализовывать свой алгоритм, например “в столбик”, либо найти более оптимальный путь.

Арифметические действия над упакованными BCD-числами

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

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

daa (Decimal Adjust for Addition) — коррекция результата сложения для представления в десятичном виде.
Команда daa преобразует содержимое регистра al в две упакованные десятичные цифры по алгоритму, приведенному в описании команды daa .
Получившаяся в результате сложения единица (если результат сложения больше 99) запоминается в флаге cf, тем самым учитывается перенос в старший разряд.

Проиллюстрируем сказанное на примере сложения двух двузначных BCD-чисел в упакованном формате (листинг 12). В приведенном примере все достаточно прозрачно, единственное, на что следует обратить внимание, — это описание упакованных BCD-чисел и порядок формирования результата. Результат формируется в соответствии с основным принципом работы микропроцессоров Intel: младший байт по младшему адресу.

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

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

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

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

Учебный курс. Урок 9. Сложение и вычитание

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

Сложение — команда ADD

Инструкция ADD выполняет сложение двух операндов. ADD можно «скармливать» числа со знаком и без (такова специфика дополнительного кода). Обязательным правилом является равность операндов по размеру, между собой можно складывать только два 16-битных числа или два 8-битных.

В первый операнд (приемник) будет помещен результат операции сложения. Многие инструкции придерживаются этого правила.

Работа этой инструкции изменяет флаги процессора. В силу того, что результат может выйти за диапазон приемника (переполнение), стать отрицательным, равным нулю и т.д. поведение флагов позволяет следить за результатом выполнения программы. Интерпретация значения флагов во много зависит от того, воспринимает ли программа операнды как числа со знаком или без:

  • Флаг CF становится равным единице, если складываемые операнды являются знаковыми и результат вышел за пределы приемника и случился перенос из старшего разряда. CF = 1 при сложении беззнаковых операндов указывает на переполнение и некорректный результат.
  • Флаг OF = 1 говорит, что произошло переполнение при сложении чисел со знаком.
  • Флаг SF имеет смысл только для операндов со знаком. SF = 1 если результат отрицательный, и SF = 0, если результат положительный. В случае с беззнаковыми операндами он просто получает значение старшего бита приемника.
  • Флаг ZF = 1 указывает, что результат равен нулю.
  • Флаг PF указывает на бинарную четность результата. Это означает что двоичное представление результата содержит четное количество единиц и нулей. Например: 0010111b.

Пример использования команды add:

Вычитание — команда SUB

Инструкция SUB выполняет вычитание операндов. Как и в случае с инструкцией ADD результат операции помещается в первый операнд (приемник). Аналогично изменяются флаги процессора.

На самом деле процессор не умеет вычитать числа. Он все делает через сложение Просто перед сложением он подменяет знак второго операнда на противоположный. Так что между инструкциями SUB и ADD даже больше общего.

Ну а чтобы изменить знак числа, когда нам нужно, есть специальная инструкция NEG. Инструкция принимает единственный операнд, знак которого меняется на противоположный.

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

Инструкции INC и DEC. Инкремент и декремент

Нередко в теле программы то или иное число нужно увеличить или убавить ровно на единицу. В программировании прибавление к операнду единицы называется инкрементом, а вычитание единицы от операнда — декрементом. Инструкции INC и DEC принимают единственный операнд. Выполнение этих инструкций не меняет значение флага CF, что является важной деталью.

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

Предлагаю закрепить полученные знания, создав маленькую программу. Нам нужно написать код, который вернет результат вычисления формулы: x = a — (b — c + 1) + (-d). Каждая переменная представляет целое 8-битное число со знаком. Переменные объявим и присвоим им значения в конце кода программы. Пример такой программы:

Арифметические операции над двоично-десятичными числами

Арифметические действия над неупакованными BCD-числами

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

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

Назначение этих команд — в корректировке результата работы обычных арифметических команд для случаев когда операнды в них являются BCD-числами.

В случае вычитания в примере 10 видно, что полученный результат нужно корректировать. Для коррекции операции сложения двух однозначных неупакованных BCD-чисел в системе команд микропроцессора существует специальная команда

aaa (ASCII Adjust for Addition) — коррекция результата сложения для представления в символьном виде.

  • если это значение меньше 9, то флаг cf сбрасывается в 0 и осуществляется переход к следующей команде;
  • если это значение больше 9, то выполняются следующие действия:
    • к содержимому младшей тетрады al (но не к содержимому всего регистра!) прибавляется 6, тем самым значение десятичного результата корректируется в правильную сторону;
    • флаг cf устанавливается в 1, тем самым фиксируется перенос в старший разряд, для того чтобы его можно было учесть в последующих действиях.

    • во-первых, такой порядок удовлетворяет общему принципу представления данных для микропроцессоров Intel;
    • во-вторых, это очень удобно для поразрядной обработки неупакованных BCD-чисел, так как каждое из них занимает один байт.

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

    aas (ASCII Adjust for Substraction) — коррекция результата вычитания для представления в символьном виде.

    • если ее значение меньше 9, то флаг cf сбрасывается в 0 и управление передается следующей команде;
    • если значение тетрады в al больше 9, то команда aas выполняет следующие действия:
      1. из содержимого младшей тетрады регистра al (заметьте — не из содержимого всего регистра) вычитает 6;
      2. обнуляет старшую тетраду регистра al;
      3. устанавливает флаг cf в 1, тем самым фиксируя воображаемый заем из старшего разряда.

    Умножение неупакованных BCD-чисел

    Для того чтобы умножать числа произвольной размерности, нужно реализовать процесс умножения самостоятельно, взяв за основу некоторый алгоритм умножения, например “в столбик”.

    • поместить один из сомножителей в регистр al (как того требует команда mul);
    • поместить второй операнд в регистр или память, отведя байт;
    • перемножить сомножители командой mul (результат, как и положено, будет в ax);
    • результат, конечно, получится в двоичном коде, поэтому его нужно скорректировать.

    aam (ASCII Adjust for Multiplication) — коррекция результата умножения для представления в символьном виде.

    • делит al на 10;
    • результат деления записывается так: частное в al, остаток в ah.

    В листинге 10 приведен пример умножения BCD-числа произвольной размерности на однозначное BCD-число. Данную программу можно легко модифицировать для умножения BCD-чисел произвольной длины. Для этого достаточно представить алгоритм умножения “в столбик”. Листинг 10 можно использовать для получения частичных произведений в этом алгоритме. После их сложения со сдвигом получиться искомый результат.

    Перед окончанием обсуждения команды aam необходимо отметить еще один вариант ее применения. Эту команду можно применять для преобразования двоичного числа в регистре al в неупакованное BCD-число, которое будет размещено в регистре ax: старшая цифра результата в ah, младшая — в al. Понятно, что двоичное число должно быть в диапазоне 0. 99.

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

    aad (ASCII Adjust for Division) — коррекция деления для представления в символьном виде.

    • умножить старшую цифру исходного BCD-числа в ax (содержимое ah) на 10;
    • выполнить сложение ah + al, результат которого (двоичное число) занести в al;
    • обнулить содержимое ah.

    Деление неупакованных BCD-чисел иллюстрируется листингом 11. Аналогично aam, команде aad можно найти и другое применение — использовать ее для перевода неупакованных BCD-чисел из диапазона 0. 99 в их двоичный эквивалент.

    Для деления чисел большей разрядности, так же как и в случае умножения, нужно реализовывать свой алгоритм, например “в столбик”, либо найти более оптимальный путь.

    Арифметические действия над упакованными BCD-числами

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

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

    daa (Decimal Adjust for Addition) — коррекция результата сложения для представления в десятичном виде.
    Команда daa преобразует содержимое регистра al в две упакованные десятичные цифры по алгоритму, приведенному в описании команды daa .
    Получившаяся в результате сложения единица (если результат сложения больше 99) запоминается в флаге cf, тем самым учитывается перенос в старший разряд.

    Проиллюстрируем сказанное на примере сложения двух двузначных BCD-чисел в упакованном формате (листинг 12). В приведенном примере все достаточно прозрачно, единственное, на что следует обратить внимание, — это описание упакованных BCD-чисел и порядок формирования результата. Результат формируется в соответствии с основным принципом работы микропроцессоров Intel: младший байт по младшему адресу.

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

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

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

    Иллюстрированный самоучитель по задачам и примерам Assembler

    Прежде чем программировать, запишите программу в псевдокодах.

    Д. Ван Тассел

    Сложение чисел размером 1 байт без учета знака

    Программа учитывает возможное переполнение результата. Сложение двоичных чисел большей размерности (2/4 байта) выполняется аналогично. Для этого необходимо заменить директивы DB на DW/DD и регистр AL на АХ/ЕАХ.

    Сложение чисел размером N байт без учета знака

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

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

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

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