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

Контрольні запитання:

1. Для чого використовується багатомодульне програмування?

2. Як описати процедуру, доступну зовнішнім модулям?

3. Які способи передачі параметрів можна використовувати?

4. Що визначає директива PUBLIC? Який формат її використання?

5. Що визначає директива EXTRN? Який формат її використання?

6. Як використовувати спільні сегменти ?

7. Що і в якому порядку записується в стек при між сегментному виклику процедури?

Література:

1.Р.Джордейн.Справочник програмиста персональных компъютеров типа ІBM PC XT и AT. - M."Финансы и статистика",1992,стор.13-31.

2.Л.О.Березко,В.В.Троценко. Особливості програмування в турбо-асемблері. -Киів,НМК ВО,1992.

3.Л.Дао. Программирование микропроцессора 8088.Пер.с англ.-М."Мир",1988.

4.П.Абель.Язык ассемблера для ІBM PC и программирования. Пер. з англ.-М.,"Высшая школа",1992.

Завдання:

  1. Створити *.exe програму, яка реалізовує обчислення, заданого варіантом виразу.

Програма повинна складатися з чотирьох модулів: головний модуль – містить спільний сегмент стеку, необхідні дані та виклик основних процедур; модуль вводу - забезпечує ввід даних з клавіатури в десятковій формі; модуль безпосередніх обчислень – здійснює всі необхідні арифметичні дії. модуль виводу – забезпечує вивід на екран результату в десятковій формі.

Всі модулі повинні бути в різних файлах і об’єднані на етапі лінкування. Передача параметрів може здійснюватися довільним чином.

  1. Переконатися у правильності роботи кожного модуля зокрема та програми загалом.

  2. Скласти звіт про виконану роботу з приведенням тексту програми та коментарів до неї.

  3. Дати відповідь на контрольні запитання.

Варіанти завдання – див. Лабораторну роботу №4.

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

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

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

X=A-B+C/D-E*F

де A=56982h; B=25h; C= A60h; D=10h, E=30h; F=2h.

Текст модулів, що відповідають поставленому завданню, містяться у каталозі LABA9.

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

; main.asm головна програма

DOSSEG

EXTRN Input :FAR, Calculation :FAR, Output :FAR

PUBLIC erFlag

STACKSG SEGMENT PARA STACK 'Stack'

DW 127 DUP(0)

STACKSG ENDS

DATASG SEGMENT PARA PUBLIC 'Data'

erFlag DB 0

DATASG ENDS

CODESG SEGMENT PARA PUBLIC 'Code'

main:

ASSUME CS:CODESG,DS:DATASG,SS:STACKSG

MOV AX,DATASG

MOV DS,AX

CALL Input

cmp erFlag,0

jne A30

CALL Calculation

cmp erFlag,0

jne A30

CALL Output

cmp erFlag,0

jne A30

A30:

mov ah,4Ch

int 21h

CODESG ENDS

END main

В модулі Input міститься оголошення зовнішньої змінної erFlag та загальнодоступних змінних B,C,D,E,F, що є визначені в сегменті даних даного модуля. Крім того, сама процедура Input оголошується як FAR та PUBLIC, що дає змогу викликати її з головної програми. Сегмент коду містить, також, опис локальних процедур, необхідних для функціонування модуля - input_variable та CHECK_BYTE та макрокоманду множення MY_MUL. Вони директив доступності (PUBLIC) не мають. Сегмент даних містить повідомлення та змінні необхідні лише для вводу даних ти їх перетворення в шістнадцяткову форму.

erFlag – змінна, що містить ознаку помилки. В даному модулі вона формується у разі некоректно введеного символу, або якщо введене значення не відповідає діапазону.

;Input.asm модуль вводу даних

DOSSEG

EXTRN erFlag:BYTE

PUBLIC B,C,D,E,F

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

DATASG SEGMENT PARA PUBLIC 'Data'

B db 00h

C dw 00h

D db 00h

E db 00h

F db 00h

TempStr db 10 dup (0)

TempBin dw 0,0

MaxLen dw 0

Mult10 dw 1,0

my_z dw 0,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,'$'

DATASG ENDS

CODESG SEGMENT PARA PUBLIC 'CODE'

ASSUME DS:DATASG, CS:CODESG

input proc FAR

public Input

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 erFlag,1

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 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

input_variable PROC

mov si,0

In_00:mov ah,01

int 21h

cmp al,0Dh

je In_1

cmp al,'-'

jne In_0

mov FlagSign,1

jmp In_00

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

LEA DX,erSTR1

MOV AH,09

INT 21H

mov erFlag,1

jmp In_5

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 erFlag,1

jmp In_5

In_3:cmp FlagSign,1

jne In_4

mov bx,0

sub bx,ax

mov ax,bx

mov bx,0

sbb bx,dx

mov dx,bx

In_4: mov [di],ax

mov [di+2],dx

mov TempBin,0

mov TempBin+2,0

mov Mult10,1

mov Mult10+2,0

mov FlagSign,0

In_5: RET

input_variable ENDP

CHECK_BYTE PROC

sub dl,30h

cmp dl,00

jl ErS

cmp dl,0Ah

jl GO

ErS: LEA DX,erSTR2

MOV AH,09

INT 21H

GO: RET

CHECK_BYTE ENDP

CODESG ENDS

END

В модулі Calc міститься оголошення зовнішніх змінних B,C,D,E,F та загальнодоступної змінної X, що є визначеною в сегменті даних даного модуля і буде отримана як результат обчислення заданого виразу. В сегменті даних, також, визначається задана у виразі константа та повідомлення та змінні необхідні лише арифметичних обчислень. Сегмент коду містить процедуру Calculation, оголошену як FAR та PUBLIC, що дає змогу викликати її з головної програми.

; calc.asm модуль обчислень

DOSSEG

EXTRN B:BYTE,C:WORD,D:BYTE,E:BYTE,F:BYTE

PUBLIC X;,MESSG_Sign

DATASG SEGMENT PARA PUBLIC 'Data'

K_low EQU 6982h

K_high EQU 0005h

Temp1 dw 00h,00h

Temp2 dw 00h

Temp3 dw 00h

;Temp4 dw 00h,00h

X dw 00h,00h

DATASG ENDS

CODESG SEGMENT PARA PUBLIC 'CODE'

ASSUME DS:DATASG, CS:CODESG

MOV AX,DATASG

MOV DS,AX

calculation proc Far

public calculation

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

CODESG ENDS

END

В модулі Output міститься оголошення зовнішньої змінної X. Сама процедура Output оголошується як FAR та PUBLIC, що дає змогу викликати її з головної програми. Сегмент коду містить також, опис локальної процедури MY_DIV2 необхідної для переводу у десяткову систему числення. Сегмент даних містить повідомлення та змінні необхідні для виводу результату на екран в десятковій формі зі знаком.

;Output.asm модуль виводу результату

DOSSEG

EXTRN X:DWORD;, MESSG_Sign :BYTE

DATASG SEGMENT PARA PUBLIC 'Data'

X_Str db 10 dup (0)

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

X_div2 dw 0,0

Y_div2 dw 0

DATASG ENDS

CODESG SEGMENT PARA PUBLIC 'CODE'

ASSUME DS:DATASG, CS:CODESG

MOV AX,DATASG

MOV DS,AX

output PROC FAR

Public output

mov di,0

mov Y_div2,10

mov cx,word ptr X

mov bx,word ptr 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

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

CODESG ENDS

END

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