Как сложить 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 заменить на 0 и наоборот);
  • к полученному числу прибавить 1.

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

Пример 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:

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

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

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

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