Задать вопрос
impressive17
@impressive17

Как реализовать вычитание с заемом?

Подскажите как реализовать вычитание с заемом с помощью команды SUB [src,] dst, команды ветвления по переносу и вычитания единицы.
  • Вопрос задан
  • 301 просмотр
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
4el_C_Foruma
@4el_C_Foruma
Чел с форума, знаток интернета
Эту команду можно использовать для вычитания 64-разрядных чисел на 32-разрядных процессорах, или 32-разрядных чисел на 16-разрядных процессорах.

В первом случае можно использовать пары регистров EDX:EAX и EBX:ECX, а во втором DX:AX и BX:CX. Если при вычитании значений в младших регистрах произошёл заём, то он будет учтён при вычитании старших слов.

Пример:

.model tiny
.code
ORG 100h

start:

MOV DX, 1 ;В паре DX:AX (0001:0000)
MOV AX, 0 ;32-разрядное число 65536
MOV BX, 0 ;В паре BX:CX
MOV CX, 1 ;32-разрядное число 1
;65536 - 1 = 65535, то есть после вычитания
;DX:AX = 65535 (0000:FFFF)
SUB AX, CX ;AX = FFFF
SBB DX, BX ;DX = 0000

RET

END start
В этом примере мы используем 16-разрядные регистры для выполнения операции вычитания 32-разрядных чисел.

В паре регистров DX:AX у нас будет число 65536 (00010000h), которое не помещается в один 16-разрядный регистр.

От этого числа мы отнимаем число 1. Это число можно отнять как непосредственное значение, но для понимания того, что можно отнять любое другое 32-разрядное число, мы поместим единицу в пару регистров BX:CX (число будет 00000001h).

Затем сначала мы из младшего регистра первого числа вычитаем младший регистр второго числа с помощью команды SUB. Результат будет равен FFFF, поскольку мы от нуля отнимаем единицу, а флаг переноса CF будет установлен.

Затем с помощью команды SBB мы от старшего регистра первого числа отнимаем старший регистр второго числа (от единицы мы отнимаем ноль). Если бы мы использовали команду SUB, то в регистре DX мы бы получили 1. То есть пара DX:AX содержала бы 32-разрядное число 1FFFFh (131071 в десятичной):

65536 - 1 = 131071

что, разумеется, неправильно.

Но мы используем команду SBB, которая кроме того, что вычитает в нашем примере из DX значение BX, ещё отнимает от результата значение флага переноса (которое в нашем примере равно 1). В итоге получаем правильное значение DX:AX = 0000:FFFF = 65535.

Ну и напоследок, как всегда, о происхождении аббревиатуры SBB.

SBB - это SuBtract with Borrow - вычитание с заимствованием.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы