Міністерство освіти і науки України
Національний університет „Львівська політехніка”
Кафедра ЕОМ
Звіт
з лабораторної роботи № 6
з дисципліни: “ Засоби системного програмування ”
на тему: “ Використання макрокоманд та процедур.Ввід даних з клавіатури та вивід результату на екран.”
Мета: набути навиків написання макрокоманд та процедур на Асемблері, освоїти способи передачі параметрів.
Реалізувати ввід та вивід даних в десятковій системі числення.
ЗАВДАННЯ:
1. Створити *.exe програму, яка реалізовує обчислення, заданого варіантом виразу над даними, введеними в десятковій системі і результат виводить на екран в десятковій формі.
Програма повинна складатися з трьох основних підпрограм:
процедура вводу - забезпечує ввід даних з клавіатури в десятковій формі і їх перевід у двійкове значення ;
процедура безпосередніх обчислень – здійснює всі необхідні арифметичні дії у двійковій системі;
процедура виводу – забезпечує перевід війкового результату у десятковий формат та вивід на екран.
Передача параметрів може здійснюватися довільним чином. Кожна з перерахованих процедур може містити довільну кількість додаткових підпрограм.
Вхідні операнди А, В, С, D, E, F вважати беззнаковими і довжиною в байтах, згідно з індексу. К – константа, довжина якої визначається значенням(згідно варіанту).
2. Переконатися у правильності роботи кожної процедури зокрема та програми загалом.
3. Скласти звіт про виконану роботу з приведенням тексту програми та коментарів до неї.
4. Дати відповідь на контрольні запитання.
Індивідуальне завдання
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 28FFh
K_high EQU 0003h
B dd ?
C dw ?
D dd ?
E dw ?
F db ?
X dd ?
Temp1 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=K+B(4)/C(2)+D(3)-E(2)/F(1) K=3FF28','$'
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,'$'
Zero db 13,10,' 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
.386
mov ax,@data
mov ds,ax
call input
call calculation
call output
mov ah,01
int 21h
mov ah,4Ch
int 21h
Zero_Eror:
mov ah,09
mov dx, offset Zero
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,10
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
cmp C,0
je Zero_Eror
LEA DX,MESSG_D
MOV AH,09
INT 21H
mov di,offset D
mov MaxLen,10
mov cx,MaxLen
call input_variable
LEA DX,MESSG_E
MOV AH,09
INT 21H
mov di,offset E
mov MaxLen,5
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
cmp F,0
je Zero_Eror
ret
input endp
calculation proc
xor ax,ax
xor dx,dx
mov ax, [E]
mov cl, [F]
div cl ; AL = AX / CL залишок в AH
mov cl,al ; переносимо результат в регістер Cx
xor ch,ch
mov ax, word ptr D ; AX = D[0]
mov dx, word ptr D+2 ; DX = D[2]
sub ax,cx ; D - E/F --> AX= AX-CX
sbb dx,0 ; якщо виникло переповнення до додати 1
mov [Temp1],ax ; зберігаюємо результат в тимчасову змінну
mov [Temp1+2],dx
mov ax,word ptr B
mov dx,word ptr B+2
div C ; AX = DX:AX/C = B/C
add [Temp1],ax ; Temp1 = Temp1 + AX == B/C+D-E/F
adc [Temp1+2],0 ; якщо виникло переповнення до додати 1
mov ax,K_low
mov dx ,K_high
add ax,[Temp1]
adc dx ,[Temp1+2]
mov word ptr X,ax
mov word ptr 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 ; заносимо введиний символ в dl
call CHECK_BYTE ; визиваємо процедуру на введення 10 числа
mov TempStr[si],dl ; зановисмо в тимчасову змінну символ який ми ввели
inc si ; збільшуємо індекс на 1
loop In_00 ; повторюємо цикл
In_1:
push si ; зберігаємо значення si в стек
dec si ; --
cmp cx,MaxLen ; перевіряємо чи cx == maxlen
jne In_2 ; якщо ні то переходимо
call Err1 ; якщо да то виводимо повідомлення про помилку
In_2:
mov bh,0 ;
mov bl,TempStr[si] ; передмо остальне значення
MY_MUL Mult10,bx,my_z ; іизиваємо функцію для переводу в 10 систему
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 ; si --
cmp si,0 ; порівнюємо чи ==0
jge In_2 ; якщо більше або рівне то переходимо
mov ax, TempBin ;
mov dx,TempBin+2;
pop si ;
cmp si,MaxLen ; перевіряємо індекс з максимальною довжиною
jl In_3 ; якщо менше то переходимо
cmp MaxLen,10 ; перевіряємо максимальну довжину з 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 ;Процес перевірки одного введеного символу на приналежність до 10-ої системи числення
PUBLIC CHECK_BYTE
sub dl,30h ; віднімаємо від введеного числа 30
cmp dl,00 ; порівнюємо чи рівно 0
jl ErS ; якщо не рівне 0 або менше то переходимо
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 ;При формуванні десяткового результату слід проводити ділення на основу числення – 10 результату Х,
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, 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
end
Додаток 1. Код програми.
Рис 1. Результат виконання
Код програми поданий в додатку 1.
Висновок: на даній роботі я набув навиків написання макрокоманд та процедур на Асемблері, освоїв способи передачі параметрів. Реалізував ввід та вивід даних в десятковій системі числення.