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

Двоичные числа. Сложение двоичных чисел.

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

.data
:summand_ldb?:первое слагаемое
;N=$-summand_1,:длина в байтах значений summand_1 и summand_2
;carry db 0:перенос сложения последних байтов
;summand_2db?; второе слагаемое
.code
.старший байт по младшему адресу
add_unsign_N macro carry.summand_l.summand_2.N
local cycl.end_p
:add_unsign_N carry,summand_1,sunmand_2.N – макрокоманда сложения без учета знака чисел
:размером N байт
:Вход: summand_1l и summanct_2 – слагаемые. N – длина в байтах.
;Порядок следования байтов – старший байт по младшему адресу (не Intel).
;Выход: summand_1или carry+summand_1 – значение суммы с учетом переполнения.
mov cl.N
mov si.N-1 cycl: moval,summand_2[si]
adc summand_l[si].al
dec si
loop cycl
jnc end_p
adc carry.0
end_p: пор
endm

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

---------------------------------------------------------------------
;add_sign – процедура сложения чисел размером 1 байт с учетом знака
:Вход: summand_1 и summandj? – слагаемые.
:Выход: sum_b или sum_w – значение суммы в зависимости от наличия расширения знака.
---------------------------------------------------------------------
.data
sum_w label word
summandl db?:значения в summand_1 и summand_2 нужно внести
carry db 0; расширение знака
summand_2 db?
.code
add_sign proc
mov al,summand_2
add summand_l.a1
jc @@cfl_ofl
jo @<acfO_ofl
:cf=0 of=0 › результат верный:cf"l of=0 › результат верный r_true
: jmp end__p результат › summand_1@icfl_ofl: jno
@@cfl_of0:cf=1 of=1 › результат неверный
mov carry.0ffh расширение знака д.б. – 1, результат › sum_w
jmp end_p
:cf=1 of=0 › результат верный
@@cfl_of0: jmp r_true результат › summand_1:cf=0 of=1 › результат неверный
@@cf0_ofl: mov carry.0.-расширение знака д.б. =0. результат › sum_w
jmp end_p end_p: ret add_sign endp

Программа учитывает возможное переполнение результата и перенос в старшие разряды. Для этого отслеживаются условия, задаваемые флагами, и выполняются действия:

  • CF=0F=0 – результат правильный и является положительным числом;
  • CF=1 0F=0 – результат правильный и является отрицательным числом;
  • CF=0F=1 – результат неправильный и является положительным числом, хотя правильный результат должен быть отрицательным (для корректировки необходимо увеличить размер результата в два раза и заполнить это расширение нулевым значением);
  • CF=0 0F=1 – результат неправильный и является отрицательным числом, хотя правильный результат должен быть положительным (для корректировки необходимо увеличить размер результата в два раза и произвести расширение знака).

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

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