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

Вычитание двоичных чисел

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

---------------------------------------------------------------------
:sub_sign_N – процедура вычитания чисел размером Н байт с учетом знака
;Вход: minuend и deduction – уменьшаемое и вычитаемое. N – длина в байтах.
:Выход: minuend – значение разности.
---------------------------------------------------------------------
.data:значения в minuend и deduction нужно внести
minuenddb? уменьшаемое
lenjninuend=$-minuend;длина в байтах уменьшаемого и вычитаемого
carry db 0 расширение знака
deduction db?;вычитаемое
.code
sub_sign_N proc
mov cx.lenjninuend
mov si.O @@ml: mov al,deduction[si]
sbb minuend[si].al
inc si
loop @@ml оценить результат:
jnc no_carry:нет заема
обрабатываем ситуацию заема из старшего разряда – получаем модуль (если нужно) N=1en_minuend+1
mov carry.0ffh
call calc_abs
jmp end_p no_carry: jns no_sign Обрабатываем ситуацию получения отрицательного результата –
:получаем модуль (если нужно) N=1en_minuend
call calc_abs
jmp end_p
no_sign: jno no_overflow
обрабатываем ситуацию переполнения – получаем модуль (если нужно)
 расширить результат знаком – получаем модуль (если нужно): N=1en_minuend+1
mov carry,0ffh
call catc_abs no_overflow: end_p: ret sub_sign_N endp

Описанная процедура вычисляет модуль разности и учитывает возможный заем из старших разрядов. Если вычисления модуля разности не требуется, то закомментируйте строки, содержащие команду CALL calc_abs. Подробности зависимости состояния флагов от результата см. в уроке "Арифметические команды" учебника.

Сегмент данных может быть задан, например, так:

.data:значения в minuend и deduction нужно внести
minuend db 25h,0f4h,0eh уменьшаемое
len_minuend=$-minuend;длина в сайтах уменьшаемого и вычитаемого
carry db 0;расширение знака
deduction db 5h,0f4h,0fh: вычитаемое

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

Вычитание с учетом знака чисел размером N байт (макрокоманда)

sub_sign_N macro minuend.deduction.N
local cycl.ml
---------------------------------------------------------------------
;sub_sign_N minuend.deduction.N – макрокоманда вычитания
;c учетом знака чисел размером N байт
:Вход: minuend и deduction – уменьшаемое и вычитаемое. N – длина в байтах.
:Порядок следования байт – старший байт по младшему адресу (не Intel).
:Выход: minuend – значение разности.
---------------------------------------------------------------------
push si
mov cl,N
mov si.N-1 cycl: moval.deduction[si]
sbbminuend[si],al: jnc ml
: neg minuend[si] ml: dec si
loop cycl
pop si
endm
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.