1. Створюю програму згідно завдання та зберігаю файл з розширенням *.asm:
MODEL SMALL
STACK 100h
DATASEG
Set_A DB 13,10,'Enter A = $'
Set_B DB 13,10,'Enter B = $'
Set_X DB 13,10,'Enter X = $'
Result DB 13,10,'Y = $'
Exit_question DB 10,13,'Exit? - [Y/N]:','$'
Error_message DB 10,13,'Error!!!',10,13,'Use only [Y] or [N]','$'
error_ db "incorrect number$"
buff db 6,7 Dup(?)
DataA dw 31h
DataB dw 33h
DataX dw 35h
Temp dw 37h
CODESEG
start:
call input_for_A
call input
mov DataA, ax
;====ввід числа А і його збереження===
call input_for_B
call input
mov DataB, ax
;====ввід числа В і його збереження===
call input_for_X
call input
mov DataX, ax
;====ввід числа X і його збереження===
cmp ax,100
jl mode2; якщо менше 40, тоді - перехід по мітці
; використовується перевірка флагів SF!= OF, відповідно до виконання команди cmp
;режим "Х >= 100"
mov bx, ax
mov ax, DataB
imul bx
sbb ax,4
;знаходжу знаменник
mov Temp, ax
;закидаю знаменник в Temp
mov ax, DataA
mov bx, 125
imul bx
push ax
mov ax, Temp
mov bx,ax
pop ax
idiv bx
adc ax,1
jmp one
mode2:
;режим "Х < 100"
mov bx, ax
mov ax, DataB
imul bx
adc ax,4
;знаходжу знаменник
mov Temp, ax
;закидаю знаменник в Temp
mov ax, DataA
mov bx, 125
imul bx
push ax
mov ax, Temp
mov bx,ax
pop ax
idiv bx
sbb ax,1
one:
call output
ask:
mov dx,OFFSET Exit_question; посилання на повідомлення-запитання
|
|
mov ah,09h; функція DOS виводу стрічки
int 21h
mov ah,01h; отримати дані вводу одного символа
int 21h
cmp al,'Y'; велика буква Y
jz exit
cmp al,'y'
jz exit
cmp al,'N'; велика буква N
jnz next2
jmp start
next2:
cmp al,'n'
jnz next1
jmp start
next1:
Show_error:
mov dx,OFFSET Error_message; посилання на повідомлення-запитання
mov ah,09h; функція DOS виводу стрічки
int 21h
jmp ask
exit:
mov ah,04ch; функція DOS завершення програми
int 21h; завершити програму
input_for_A:
mov ax,@Data
mov ds,ax; встановити регістр DS таким чином, щоб він вказував на сегмент даних
mov dx,OFFSET Set_A; посилання на повідомлення-запитання
mov ah,09h; функція DOS виводу стрічки
int 21h
ret
input_for_B:
mov ax,@Data
mov ds,ax; встановити регістр DS таким чином, щоб він вказував на сегмент даних
mov dx,OFFSET Set_B; посилання на повідомлення-запитання
mov ah,09h; функція DOS виводу стрічки
int 21h
ret
input_for_X:
mov ax,@Data
mov ds,ax; встановити регістр DS таким чином, щоб він вказував на сегмент даних
mov dx,OFFSET Set_X; посилання на повідомлення-запитання
mov ah,09h; функція DOS виводу стрічки
int 21h
ret
input:
;Зчитування числа з клавіатури і перетворення його в цифрове значення;Результат в регістрі
mov ah,0ah
xor di,di
mov dx,offset buff; адреса буфера
int 21h; зчитуємо стрічку
mov dl,0ah
mov ah,02
int 21h; виводимо перевід стрічки
; обробляємо вміст буфера
mov si,offset buff+2; берем аддрес початку стрічки
cmp byte ptr [si],"-"; якщо перший символ мінус
jnz ii1
mov di,1; встановлюємо прапор
inc si; і пропускаєм його
ii1:
xor ax,ax
mov bx,10
ii2:
mov cl,[si]; берем символ з буфера
cmp cl,0dh; перевіряємо чи він не останній
jz endin
; якщо символ не останній, то перевіряємо його на правильність
cmp cl,'0'; якщо введений невірний символ <0
jl er
cmp cl,'9'; якщо введений невірний символ >9
|
|
ja er
sub cl,'0'; робимо з символа число
mul bx; перемножуємо на 10
add ax,cx; додаємо до остальнх
inc si; вказівник на наступний символ
jmp ii2; повторюємо
er:; якщо була помилка, то виводимо повідомлення про це
mov dx, offset error_
mov ah,09
int 21h
int 20h
; всі символи з буфера оброблені число находится в ax
endin:
cmp di,1; якщо встановлений прапор, то
jnz ii3
neg ax; робимо число від’ємним
ii3:
;Завершення функції зчитування і розпізнавання числа
ret
output:
xchg cx,ax
mov dx,OFFSET Result; вказує на
mov ah,09h; функція DOS виводу повідомлення
int 21h; вивести відповідне повідомлення
xchg cx,ax
;mov ax, 0
;Початок функції перетворення числа в стрічку і виводу її на екран ******
; Число для виводу в регістрі AX
; Перевіряємо число на знак
test ax, ax
jns oi1
; Якщо воно від'ємне, виведемо мінус і залишимо його модуль.
mov cx, ax
mov ah, 02h
mov dl, '-'
int 21h
mov ax, cx
neg ax
; Кількість цифр будемо тримати в CX.
oi1:
xor cx, cx
mov bx, 10; основа сс. 10 для десяткової і т.п.
oi2:
xor dx,dx
div bx
; Ділимо число на основу сс. В залишку получається остання цифра.
; Відразу виводити її неможна, тому збережемо її в стек.
push dx
inc cx
; А с діленим повторюємо те ж саме, відділюючи від нього чергову
; цифру справа, поки не залишиться нуль, що значить, що дальше
; зліва тільки нулі.
test ax, ax
jnz oi2
; Тепер приступимо до виводу.
mov ah, 02h
oi3:
pop dx
; Беремо чергову цифру, переводимо її в символ и виводимо.
add dl, '0'
int 21h
; Повторимо рівно стільки разів, скільки цифр нарахували.
loop oi3
; Завершення функції перетворення числа в стрічку і виводу її на екран
ret
end start
2.Асемблюю програму з допомогою TASM та перевіряю її на наявність помилок.
3.Компоную програму з допомогою TLINK, в результаті чого отримую виконуваний ехе-файл.
4. Запускаю скомпільовану програму.
Висновок: на лабораторній роботі я вивчив правила оголошення та використання змінних в мові програмування Асемблер та навчився застосовувати стек та підпрограми.