МЕТА: ОСВОЇТИ ВИКОРИСТАННЯ КОМАНД ПОРІВНЯННЯ, УМОВНОГО ТА БЕЗУМОВНОГО ПЕРЕХОДІВ. НАБУТИ ВМІННЯ ВИКОРИСТОВУВАТИ АРИФМЕТИЧНІ КОМАНДИ НАД ЗНАКОВИМИ ДАНИМИ ТА КОМАНДИ ЛОГІЧНИХ ОПЕРАЦІЙ.
Заданий вираз:
Аналіз задачі.
Можливі два випадки ділення на нуль, які слід виявити і видати відповідне повідомлення, не переходячи до безпосередніх обчислень:
1) якщо і і ;
2) якщо і і .
Водночас, випадок коли є цілком допустимим.
Оскільки вхідні дані є знаковими, то для організації програми слід використовувати відповідні команди переходів та команди арифметики (в даному випадку ділення) знакових чисел.
Для уникнення можливого переповнення (при виконанні ділення), слід перейти до більшої розрядності операндів, тобто використати формат ділення 4 байт на 2 байти, при цьому сформувавши у відповідних регістрах коректні знакові числа, тобто розмножити старший біт вхідних даних.
Оскільки за умовою завдання всі вхідні дані є однобайтними і у виразі відсутня операція множення, то очевидно, що для результату достатньо передбачити два байти
DOSSEG
.MODEL SMALL
.STACK 100h
.DATA
A db 0
B db 35h
X dw 0
Hello db 13,10,' X=a/b+1 if a<b',13,10,' X=-71 if a==b',13,10,' X=(b-9)/a if a>b',13,10,'$'
A_B db 13,10, ' a==b ====> X=-365',13,10,'$'
Error_A db 13,10,' a>b and a==0 ----> divide by zero',13,10,'$'
Error_B db 13,10,' a<b and b==0 ----> divide by zero',13,10,'$'
.CODE
mov ax,@data
;Перевизначення сегментного регістру ds
mov ds,ax
mov ah,09
;Вивід текстового повідомлення про умову задачі
mov dx,offset hello
int 21h
mov al,A
;занести значення з комірки пам’яті, визначеної міткою А, у регістр al
cmp al,B
;порівняти значення регістру al та комірки пам’яті В
jne A_n_B
;за умови, що вони нерівні, перейти на мітку A_n_B
mov X,-365
;інакше – занести значення константи -365 у пам’ять, визначену як X
mov ah,09
;вивести повідомлення, про рівність вхідних даних і значення результату
mov dx,offset A_B
int 21h
jmp exit
;перейти на мітку exit
A_n_b: jg A_g_B
;якщо вміст al > В, то перейти на мітку A_g_B
cmp B,0
;інакше – порівняти значення В з нулем
je exit_B
;якщо вони рівні, тобто можливе ділення на нуль, перейти на мітку exit_B
mov cl,3
;занести у регістр ch константу 3
imul cl
;виділити в регістрі ah знаковий розряд значення, занесеного у регістр al
sub ax,6 ;ax=a-6
;відняти число 9 від значення у регістрі ах
mov dx,8000h
;занести у регістр dh константу 8000h
and dx,ax
;виділити в регістрі dx знаковий розряд значення, занесеного у регістр ax
sar dx,15
;розповсюдити знаковий розряд в регістрі dx
mov bl,A
;занести у регістр bl значення з комірки пам’яті, визначеної міткою А
mov bh,80h
;занести у регістр bh константу 80h
and bh,bl
;виділити в регістрі bh знаковий розряд значення, занесеного у регістр bl
sar bh,8
;розповсюдити знаковий розряд в регістрі bh
idiv bx
;поділити знакове число, що знаходиться у регістровій парі dx:ax на знакове число ;у регістрі bx
mov X,ax
;перенести отриманий результат у комірку Х
jmp exit
;перейти на мітку exit
exit_B: mov ah,09
;вивести повідомлення про ділення на нуль, при В==0
mov dx,offset Error_B
int 21h
jmp exit
;перейти на мітку exit
A_g_B: cmp A,0
;порівняти значення A з нулем
je exit_A
;якщо вони рівні, тобто можливе ділення на нуль, перейти на мітку exit_А
mov al,A
;занесети значення з комірки пам’яті, визначеної міткою В, у регістр al
mov ah,80h
;занести у регістр ah константу 80h
and ah,al
;виділити в регістрі ah знаковий розряд значення, занесеного у регістр al
sar ah,8
;розповсюдити знаковий розряд в регістрі ah
mov dl,ah
;перенести знаковий розряд в регістр dl
mov dh,dl
;перенести знаковий розряд в регістр dh
mov bl,B
;занести у регістр bl значення з комірки пам’яті, визначеної міткою В
mov bh,80h
;занести у регістр bh константу 80h
and bh,bl
;виділити в регістрі bh знаковий розряд значення, занесеного у регістр bl
sar bh,8
;розповсюдити знаковий розряд в регістрі bh
idiv bx
;поділити знакове число, що знаходиться у регістровій парі dx:ax на знакове число ;у регістрі bx
add ax,-5
; до отриманого двобайтного результату додати значення -5
mov X,ax
;перенести отриманий результат у комірку Х
jmp exit
;перейти на мітку exit
exit_A: mov ah,09
;вивести повідомлення про ділення на нуль, при А==0
mov dx,offset Error_A
int 21h
exit:
mov ah,4Ch
;завершення програми
int 21h
end