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

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

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

---------------------------------------------------------------------
;sub_unsign – процедура вычитания чисел размером 1 байт без учета знака
;Вход: minuend и deduction – уменьшаемое и вычитаемое.
:Выход: minuend – результат вычитания
.---------------------------------------------------------------------
.data значения в minuend и deduction нужно задать
minuend db? уменьшаемое
deduction db?;вычитаемое
.code
sub_unsign proc
mov al.deduction
subminuend.al:оценить результат на случай уменьшаемое < вычитаемого
jnc end_p; нет заема обрабатываем ситуацию заема из старшего разряда – получаем модуль (если нужно)
neg minuend end_p: ret sub_unsign endp

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

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

---------------------------------------------------------------------
:sub_unsign_N – . процедура вычитания чисел размером N байт без учета знака
:Вход: minuend и deduction – уменьшаемое и вычитаемое, N – длина в байтах.
;Выход: minuend – значение разности.
---------------------------------------------------------------------
.data значения в minuend и deduction нужно внести
minuenddb? уменьшаемое
N=$-minuend;длина в байтах значений minuend и deduction '.
deduction db?:вычитаемое
.code
sub_unsign_N proc
mov cl.N
xor si,si cycl: moval,deduction[si]
sbbminuend[si].al
jnc @@ml
negminuendtsi] @@ml: inc si
loop cycl
ret sub_uns1gn_N endp

Программа учитывает возможный заем из старших разрядов. Длина уменьшаемого должна быть не меньше длины вычитаемого, недостающие разряды вычитаемого должны быть нулевыми. В любом случае, результат – абсолютное значение.

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

.data
N equ5;длина в байтах значений minuend и deduction
minuenddb 30.43.65.230.250 уменьшаемое
deduction db 45.34.65.78.250;вычитаемое

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

---------------------------------------------------------------------
;sub_sign – процедура вычитания чисел размером 1 байт с учетом знака
;Вход: minuend и deduction – уменьшаемое и вычитаемое.
:Выход: minuend – значение разности.
---------------------------------------------------------------------
.data значения в minuend и deduction нужно внести
N equ 2:длина в байтах результата в ситуации расширения знака для получения его модуля
minuend db? – . уменьшаемое
carry db 0 расширение знака
deduction db?:вычитаемое
.code
sub_sign proc
mov al.deduction
subminuend.al;оценить результат:
jnc no_carry:нет заема обрабатываем ситуацию заема из старшего разряда – получаем модуль
 (если нужно)
neg minuend
jmp end_p
no_carry: jns no_sign обрабатываем ситуацию получения отрицательного результата – получаем модуль
 (если нужно)
neg minuend
jmp end_p
no_sign: jno no_overflow обрабатываем ситуацию переполнения – получаем модуль (если нужно).
расширить результат знаком – получаем модуль (если нужно):
mov carry.0ffh
call calc abs no_overflow:
endjr ret sub_sign endp

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.