Міністерство освіти і науки
Національний університет «Львівська політехніка»
Кафедра ЕОМ
Звіт
до лабораторної роботи № 7
з дисципліни: “ Засоби системного програмування”
на тему: “ Багатомодульне програмування”
Львів – 2016
Мета роботи
• Оволодіти навиками створення багатомодульних програм. Засвоїти правила взаємодії різних модулів.
Завдання
Створити *.exe програму, яка реалізовує обчислення, заданого варіантом виразу.
Програма повинна складатися з чотирьох модулів:головний модуль – містить спільний сегмент стеку, необхідні дані та виклик основних процедур;модуль вводу - забезпечує ввід даних з клавіатури в десятковій формі;модуль безпосередніх обчислень – здійснює всі необхідні арифметичні дії. модуль виводу – забезпечує вивід на екран результату в десятковій формі.
Всі модулі повинні бути в різних файлах і об’єднані на етапі лінкування. Передача параметрів може здійснюватися довільним чином.
Переконатися у правильності роботи кожного модуля зокрема та програми загалом.
Скласти звіт про виконану роботу з приведенням тексту програми та коментарів до неї.
Дати відповідь на контрольні запитання.
Індивідуальне завдання(Варіант 27):
№
Вираз
K
27
X=A2*B1+C4/(K-E1*F1)
7A7627
Текст програми:
main.asm
DOSSEG
EXTRN input:FAR, calculation:FAR, Output:FAR
PUBLIC A,B,C,E,F,X
STACKSG SEGMENT PARA STACK 'Stack'
DW 127 DUP(0)
STACKSG ENDS
DATASG SEGMENT PARA PUBLIC 'Data'
A dw 0
B db 0
C dd 0
E db 0
F db 0
X dd 0
DATASG ENDS
CODESG SEGMENT PARA PUBLIC 'Code'
start:
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG
MOV AX,DATASG
MOV DS,AX
call input ;процедура вводу з клавіатури
call calculation ;обчислення виразу
call output ;виводу результату
mov ah,01
int 21h
mov ah,4Ch
int 21h
CODESG ENDS
end start
input.asm
EXTRN A:WORD,B:BYTE,C:DWORD,E:BYTE,F:BYTE
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'
MESSG_X DB 13,10,'X=A2*B1+C4/(K-E1*F1) K=7A7627h','$'
MESSG_A DB 13,10,'A = ','$'
MESSG_B DB 13,10,'B = ','$'
MESSG_C DB 13,10,'C = ','$'
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,' F = 0 --> divide by zero ',13,10,'$'
erStr3 db 13,10,'Data is too long ',13,10,'$'
TempStr db 10 dup (0)
TempBin dw 0,0
MaxLen dw 0
Mult10 dw 1,0
my_z dw 0,0
DATASG ENDS
CODESG SEGMENT PARA PUBLIC 'CODE'
ASSUME DS:DATASG, CS:CODESG
input proc far
public input
LEA DX,MESSG_X ; lea завантажує ефективну адресу MESSG_X
MOV AH,09
INT 21H
LEA DX,MESSG_A
MOV AH,09
INT 21H
mov di,offset A
mov MaxLen,5
mov cx,MaxLen
call input_variable
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,9
mov cx,MaxLen
call input_variable
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
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
CODESG ENDS
END
calc.asm
EXTRN A:WORD,B:BYTE,C:DWORD,E:BYTE,F:BYTE, X:DWORD
DATASG SEGMENT PARA PUBLIC 'Data'
K_low EQU 7627h
K_high EQU 7Ah
temp1 dw 0
temp2 dw 0
temp3 dw 0
temp4 dw 0
DATASG ENDS
CODESG SEGMENT PARA PUBLIC 'CODE'
ASSUME DS:DATASG, CS:CODESG
calculation proc far
public calculation
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
; множення temp1=A*B
mov al, byte ptr A
mul B
mov word ptr temp1,ax
mov al, byte ptr [A+1]
mul B
add word ptr [temp1+1], ax
adc byte ptr [temp1+3], 0 ;додавання можливого переносу в старший байт змінної
; для демонстрації в дебагері
mov ax, word ptr [temp1+2]
mov bx, word ptr temp1
; множення temp2=E*F
mov al, byte ptr E
mul F
mov word ptr temp2,ax
mov al, byte ptr [E+1]
mul F
add word ptr [temp2+1], ax
adc byte ptr [temp2+3], 0 ;додавання можливого переносу в старший байт змінної
; для демонстрації в дебагері
mov ax, word ptr [temp2+2]
mov bx, word ptr temp2
; віднімання temp3=K-temp2
mov ax, word ptr K_low
sub ax, temp2
mov word ptr temp3, ax
mov ax, word ptr K_high
sbb ax, 0 ;віднімання з можливим запозиченням
mov word ptr [temp3+2], ax
; для демонстрації в дебагері
mov ax, word ptr [temp3+2]
mov bx, word ptr temp3
; ділення temp4=C/temp3
mov ax, word ptr C
mov dx, word ptr [C+2]
div temp3
mov temp4, ax
; додавання X=temp1+temp4
mov ax, word ptr temp1
add ax, temp4
mov word ptr X, ax
mov ax, word ptr [temp1+2]
adc ax,0
mov word ptr [X+2], ax
mov ax, word ptr [temp1+4]
adc ax,0
mov word ptr [X+4], ax
; для демонстрації в дебагері
mov ax, word ptr [X+4]
mov bx, word ptr [X+2]
mov cx, word ptr X
ret
calculation endp
CODESG ENDS
END
output.asm
EXTRN X:DWORD
DATASG SEGMENT PARA PUBLIC 'Data'
MESSG_X1 db 13,10,'X = ','$'
X_Str db 10 dup (0)
X_div2 dw 0,0
Y_div2 dw 0
DATASG ENDS
CODESG SEGMENT PARA PUBLIC 'CODE'
ASSUME DS:DATASG, CS:CODESG
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
sbb bx,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
Результати програми:
/
Рис.1 Ввід значень і вивід обчисленого результату
Висновок: в даній лабораторній роботі я навчився розділяти програму на модулі, використовуючи при цьому для даних і процедур ключові слова public і extrn, також я вивчив різні методи передачі параметрів між модулями.