Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LABA06_2012.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
442 Кб
Скачать
☆

Приклад виконання.

Завдання: Написати програму, яка обчислює арифметичний вираз над даними, введеними в десятковій системі і результат виводить на екран в десятковій формі. Оформити програму в вигляді виклику трьох процедур : вводу, обчислень, виводу.

Заданий вираз:

X=К-B1+C2/D1-E1*F1 К=56982h

Згідно з завданням, в кодовому сегменті повинен бути виклик трьох процедур та їх опис. Відповідно, структура програми буде мати такий вигляд.

DOSSEG

.MODEL SMALL

; опис макросів

.STACK 100h

.DATA

; опис необхідних даних

.CODE

mov ax,@data

mov ds,ax

call INPUT

call CALCULATION

call OUTPUT

INPUT proc

;тіло процедури вводу

ret

INPUT endp

CALCULATION proc

;тіло процедури обчислень

ret

CALCULATION endp

OUTPUT proc

;тіло процедури виводу результатів

ret

OUTPUT endp

mov ah,4Ch

int 21h

END

Програма, що обраховує даний вираз була приведена в лабораторній роботі №3. Згідно з нею, вхідні дані повинні знаходитися в пам’яті за адресами від В до F, а результат – за міткою Х. Тепер, слід оформити цю програму у вигляді процедури та написати відповідні підпрограми, щоб забезпечити коректний ввід в десятковій формі, перевід в шістнадцяткову систему та зворотнє перетворення і вивід результату на екран.

Підпрограма вводу. – INPUT, обчислень – CALCULATION, виводу – OUTPUT.

Розглянемо можливості вводу даних. Це можна зробити двома способами:

1) для кожної змінної посимвольно вводити кожну цифру. В цьому випадку буде використовуватися функція 01h переривання 21h (оскільки функція 07h переривання 21h та функція 00 переривання 16h не забезпечують еховідображення, то їх використовувати в даному випадку недоцільно). В сегменті даних слід передбачити місце для зберігання введених символів. При чому, розмір відведеної пам’яті повинен дозволяти ввід змінної максимального розміру. В даному випадку змінна максимальний розмір має змінна С – 2 байт, тобто вона складається з 5 десяткових символів. Отже розмір тимчасової пам’яті для зберігання введених символів становить 5 байт. Значення в цьому місці пам’яті буде оновлюватися для кожної змінної.

2) вводити для кожної змінної рядок символів. В цьому випадку можна використати функцію 0Аh або 3Fh переривання 21h. При цьому у сегменті даних вимагається область вводу для кожної змінної, що значно збільшує об’єм коду і зрозумілість програми.

Оскільки ввід даних для кожної змінної буде відбуватися однаково, то варто написати процедуру вводу, яка буде викликатися 4 рази, вводячи кожен раз різну кількість символів і записуючи результат вводу, переведений в 10-ий формат, в іншу область пам’яті (процедура input_variable). Процес перевірки одного введеного символу на приналежність до 10-ої системи числення теж опишемо як окрему процедуру (процедура CHECK_BYTE). Крім того, слід передбачити перевірки на коректність діапазону введених чисел (наприклад процедура Err1).

При переводі в десяткову систему, використовується макрокоманда множення MY_MUL , яка дозволяє сформувати черговий множник, тобто степінь числа 10, та власне саме множення на нього.

Процедура обчислень нічим не відрізняється від програми з лабораторної роботи №4.

Тепер слід вивести результат, отриманий після обчислень, на екран в десятковому форматі. При формуванні десяткового результату слід проводити ділення на основу числення – 10 результату Х, який займає 4 байти. Для коректного ділення призначена підпрограма MY_DIV2.

Безпосередній вивід утвореного числа здійснити двома способами:

1) посимвольно виводити кожну цифру. В цьому випадку буде використовуватися функція 02h або 06h переривання 21h і жодних змін в сегмент даних вносити не треба.

2) утворити рядок символів і вивести результат повністю. В цьому випадку можна використати функцію 09h або 40h переривання 21h, які потребують у сегменті даних області виводу (тобто місця під майбутній рядок символів).

Згідно алгоритму перетворення, програма буде містити цикл, кількість повторів якого залежить від розміру результату (в байтах). В даному випадку цей розмір становить 4 байти. Зчитування даних повинно відбуватися послідовно по одному байту починаючи зі старшого. Оскільки змінна результату оголошена як слово, то щоб звернутися окремо до кожного байту слід використати директиву BYTE PTR та відносну адресацію через регістр [SI], значення в якому буде на одиницю відставати від лічильника циклу в регістрі CX.

Альтернативним варіантом виводу результату на екран є формування символьного рядка в пам’яті і вивід його за допомогою функції 09h переривання 21h. При цьому, в сегменті даних резервуємо місце під рядок символів довжиною 10 байт (4 байти результату це 10 символів), заповнюючи його пробілами , та додаємо ознаку завершення рядка – ‘$’. При записі чергового символу в пам’ять необхідно збільшувати лічильник символів, який адресує область виводу і знаходиться в регістрі [DI].

Нижче приведено текст програми, що реалізовує завдання.

;X=К-B(1)+C(2)/D(1)-E(1)*F(1) К=354690

DOSSEG

.MODEL SMALL

MY_MUL MACRO X,Y,Z

mov z,0

mov z+2,0

MOV AX,X

MUL Y

MOV Z,AX

MOV Z+2,DX

MOV AX,X+2

MUL Y

ADD Z+2,AX

mov ax,Z

mov dx,Z+2

ENDM

.STACK 100h

.DATA

K_low EQU 6982h

K_high EQU 0005h

B db 00h

C dw 00h

D db 00h

E db 00h

F db 00h

Temp1 dw 00h,00h

Temp2 dw 00h

Temp3 dw 00h

Temp4 dw 00h,00h

X dw 00h,00h

X_Str db 10 dup (0)

TempStr db 10 dup (0)

TempBin dw 0,0

MaxLen dw 0

X_div2 dw 0,0

Y_div2 dw 0

MESSG_X DB 13,10,'X=К-B(1)+C(2)/D(1)-E(1)*F(1) К=354690 (56982h)','$'

MESSG_B DB 13,10,'B= ','$'

MESSG_C DB 13,10,'C= ','$'

MESSG_D DB 13,10,'D= ','$'

MESSG_E DB 13,10,'E= ','$'

MESSG_F DB 13,10,'F= ','$'

MESSG_X1 DB 13,10,'X= ','$'

erStr1 db 13,10,'Data not input_variable',13,10,'$'

erStr2 db 13,10,'Incorrectly data ',13,10,'$'

erStr2_1 db 13,10,' D =0 --> divide by zero ',13,10,'$'

erStr3 db 13,10,'Data is too long ',13,10,'$'

Mult10 dw 1,0

my_z dw 0,0

.CODE

mov ax,@data

mov ds,ax

call input

call calculation

call output

mov ah,01

int 21h

mov ah,4Ch

int 21h

input proc

LEA DX,MESSG_X

MOV AH,09

INT 21H

LEA DX,MESSG_B

MOV AH,09

INT 21H

mov di,offset B

mov MaxLen,3

mov cx,MaxLen

call input_variable

LEA DX,MESSG_C

MOV AH,09

INT 21H

mov di,offset C

mov MaxLen,5

mov cx,MaxLen

call input_variable

LEA DX,MESSG_D

MOV AH,09

INT 21H

mov di,offset D

mov MaxLen,3

mov cx,MaxLen

call input_variable

cmp D,0

jne dali

mov ah,09

mov dx, offset erStr2_1

int 21h

mov ah,4Ch

int 21h

dali: LEA DX,MESSG_E

MOV AH,09

INT 21H

mov di,offset E

mov MaxLen,3

mov cx,MaxLen

call input_variable

LEA DX,MESSG_F

MOV AH,09

INT 21H

mov di,offset F

mov MaxLen,3

mov cx,MaxLen

call input_variable

ret

input endp

calculation proc

xor ax,ax

xor bx,bx

xor cx,cx

xor dx,dx

mov dx,K_high

mov ax,K_low

mov bh,00

mov bl,B

sub ax,bx

sbb dx,0

mov Temp1,ax

mov Temp1+2,dx

mov dx,0

mov ax,C

mov bh,0

mov bl,D

div bx

mov Temp2,ax

mov ax,0

mov al,E

mul F

mov Temp3,ax

mov ax,0

mov ax,Temp2

add Temp1,ax

adc Temp1+2,0

mov ax,Temp1

mov dx, Temp1+2

sub ax,Temp3

sbb dx,0

mov X,ax

mov X+2,dx

ret

calculation endp

input_variable PROC

mov si,0

In_00: mov ah,01

int 21h

cmp al,0Dh

je In_1

In_0: mov dl,al

call CHECK_BYTE

mov TempStr[si],dl

inc si

loop In_00

In_1: push si

dec si

cmp cx,MaxLen

jne In_2

call Err1

In_2: mov bh,0

mov bl,TempStr[si]

MY_MUL Mult10,bx,my_z

add TempBin,ax

adc TempBin+2,dx

mov bh,0

mov bl,10

MY_MUL Mult10,bx,my_z

mov Mult10,ax

mov Mult10+2,dx

dec si

cmp si,0

jge In_2

mov ax, TempBin

mov dx,TempBin+2

pop si

cmp si,MaxLen

jl In_3

cmp MaxLen,10

jl In_2_1

js In_Err

cmp dx,0FFFFh

ja In_Err

jmp In_3

In_2_1: cmp MaxLen,5

jl In_2_2

cmp dx,00

ja In_Err

cmp ah,0ffh

ja In_Err

jmp In_3

In_2_2: cmp ax,00FFh

jbe In_3

In_Err: LEA DX,erSTR3

MOV AH,09

INT 21H

mov ah,4Ch

int 21h

In_3: mov [di],ax

mov [di+2],dx

mov TempBin,0

mov TempBin+2,0

mov Mult10,1

mov Mult10+2,0

RET

input_variable ENDP

Err1 PROC

PUBLIC Err1

LEA DX,erSTR1

MOV AH,09

INT 21H

mov ah,4Ch

int 21h

RET

Err1 ENDP

CHECK_BYTE PROC

PUBLIC CHECK_BYTE

sub dl,30h

cmp dl,00

jl ErS

cmp dl,0Ah

jl GO

ErS: LEA DX,erSTR2

MOV AH,09

INT 21H

mov ah,4Ch

int 21h

GO: RET

CHECK_BYTE ENDP

MY_DIV2 proc

sub cx,cx

sub bx,bx

mov dx,X_div2+2

mov ax,X_div2

M2_D1:

cmp dx,Y_div2

jb M2_D3

sub ax,Y_div2

sbb dx,00

add cx,01

adc bx,0

jmp M2_D1

M2_D3:

div Y_div2

add cx,ax

adc bx,00

ret

MY_DIV2 ENDP

output PROC

mov di,0

mov Y_div2,10

mov cx,X

mov bx,X+2

O_1: mov X_div2,cx

mov X_div2+2,bx

call my_div2

add dl,30h

mov X_Str[di],dl

inc di

cmp bx,0

ja O_1

cmp cx,10

jae O_1

add cl,30h

mov X_Str[di],cl

mov dx,offset MESSG_X1

mov ah,09

int 21h

O_2:

mov dl,X_Str[di]

mov ah,02h

int 21h

dec di

jge O_2

ret

output ENDP

end

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]