;Лабораторная работа №3. ;ТЕМА: Ввод-вывод и арифметическая обработка числовых данных. ;ЗАДАНИЕ: Написать программу, выполняющую ; -ввод массива целыx многозначныx чисел со знаком. При вводе осуществляется контроль допустимости вводимыx символов. Ввод предваряется текстовым приглашением. ; -арифметическую и логическую обработку массива чисел по заданию преподавателя. ; -преобразование числового результата в ASCII-строку и отображение на дисплее. ;Индивидуальное задание: (#1)Разделить сумму исходных чисел на максимум из положительных. .MODEL SMALL ;определение модели памяти .stack 100h ;сегмент стека размером в 256 байт ;pointer macro a,b,c ;положение курсора ; mov ah,02 ;bh=номер видеостраницы, dh=строка курсора, dl=столбец курсора. ; mov bh,a ; mov dh,b ; mov dl,c ; int 10h ;endm input_string macro ist ;ввод строки символов push ax push dx mov dx,offset ist mov ah,0Ah int 21h pop dx pop ax endm Out_string macro ost ;вывод сообщений на экран push ax push dx mov dx,offset ost mov ah,9 int 21h pop dx pop ax endm .data mess1 db 'Input the number (-29999;+29999): $' ;приглашение ввода числа mess_err1 db '<< Input error! >>$' ;сообщение "Ошибка ввода" mess_err2 db '<< Buffer overflow! >>$' ;сообщение "Переполнение буфера" mess2 db 'The sum total of input numbers: $' ;сообщение "Сумма исходных чисел" mess3 db 'Maximum of positive number: $' ;сообщение "Максимум из положительных" mess4 db 'Result: $' ;сообщение "Результат" numbb label byte ;массив трактуется как байтовый numbers db 7,?,7 dup(0) ;вводимые числа massiv dw 5 dup(0) ;массив уже введеных чисел SumTot dw 0,'$' ;сумма исходных чисел MaxPos dw 0,'$' ;максимум из положительных Result dw 0,'$' ;результат деления flag_error EQU 1 ;константа = флаг ошибки out_str db 6 dup(' '),'$' perev db 0dh,0ah,'$' .code Start: mov ax,@data ;связь регистра DS с сегментом данных через AX mov ds,ax ;Видеосервис. Вызов Функции 0(ah), режим 3(al), очистка экрана. mov ah,00 mov al,03 int 10h ;цикл ввода xor di,di ;di - номер числа в массиве mov cx,5 ;в cx - размер массива input: push cx label_1: Out_string mess1 input_string numbers Out_string perev ;call AscToBin call DIAPAZON cmp bh,flag_error ;сравним bh и flag_error je err1 ;если равен -> сообщение об ошибке ввода call DOPUST cmp bh,flag_error je err1 call AscToBin inc di inc di pop cx loop input jmp label_2 err1: Out_string mess_err1 Out_string perev jmp label_1 ; ------ >>> здесь арифметическая обработка <<< ------ label_2: ;сумма исходных чисел xor si,si xor ax,ax xor bx,bx xor dx,dx mov cx,5 metka: mov bx,offset [massiv+si] add ax,bx ; jo ovr ;НАПИСАТЬ ПРОВЕРКУ НА ПЕРЕПОЛНЕНИЕ inc si inc si loop metka mov SumTot,ax Out_string perev Out_string mess2 call BinToAsc Out_string out_str Out_string perev call CLEAN ;максимум из положительных xor si,si mov cx,5 ;mov si,2 next: mov ax,offset [massiv+si] cmp ax,0 jle sled cmp ax,MaxPos jle sled mov MaxPos,ax sled: inc si inc si loop next Out_string mess3 mov ax,MaxPos call BinToAsc Out_string out_str Out_string perev call CLEAN ;результат деления xor ax,ax xor dx,dx mov ax,SumTot sub dx,dx div MaxPos jo ovr ;НАПИСАТЬ ПРОВЕРКУ НА ПЕРЕПОЛНЕНИЕ (???) mov Result,ax Out_string mess4 call BinToAsc Out_string out_str Out_string perev call CLEAN jmp quit ovr: Out_string mess_err2 ;вывод сообщения о переполнении quit: mov ah,7 int 21h mov ax,4C00h ;системный вызов DOS 4Ch: в АН помещается 4Ch, в AL - код возврата int 21h WAIT_KEY proc ;процедура ожидания нажатия клавиши mov ah,10h int 16h ret WAIT_KEY endp DIAPAZON proc ;проверка диапазона вводимых чисел (-29999;+29999) ;буфер ввода - numbers ;через bh возвращается флаг ошибки ввода. xor bh,bh cmp [numbers+1],5 ;если ввели менее 5 символов проверим их допустимость jb dop cmp [numbers+2],2dh ;если ввели 5 или более символов, проверим является ли первый минусом "-" jne plus ;если первый символ не "-", тогда проверим число символов cmp [numbers+1],6 jb dop ;если первый символ "-", а символов меньше 6 проверим допустимость символов je first_otr ;если первый символ "-", и количество равно 6, проверим первую цифру для отрицательных plus: cmp [numbers+1],6 ;введено 6 символов и первый символ не "-", тогда ошибка. je error1 ;ошибка! cmp [numbers+2],32h ;сравним первый символ с "2" jna dop ;если первый <=2 - проверим допустимость символов error1: mov bh,flag_error ;bh = flag_error ret first_otr: cmp [numbers+3],32h ;сравним первый символ с "2" jna dop ;если первый <=2 - проверим допустимость символов mov bh,flag_error ;bh = flag_error dop: ret DIAPAZON endp DOPUST proc ;проверка допустимости вводимых символов ;буфер ввода - numbers ;через bh возвращается флаг ошибки ввода, si - номер символа в строке xor bh,bh xor ah,ah xor ch,ch mov si,2 mov cl,[numbers+1] ;в cl количество введенных символов over: mov al,[numbers+si] ;в al - первый и последующие символы cmp al,2dh ;является ли символ минусом jne testdop ;если не минус - проверка допустимости cmp si,2 ;если минус - является ли он первым символом jne error2 ;если минус не первый - ошибка! jmp lower testdop: ;является ли введенный символ цифрой cmp al,30h jb error2 cmp al,39h ja error2 lower: inc si loop over jmp exit error2: mov bh,flag_error ;при недопустимости символа bh = flag_error exit: ret DOPUST endp AscToBin proc ;преобразование строки в число ;в cx количество введенных символов ;в bx - номер символа начиная с последнего ;буфер чисел - massiv, в di - номер числа в массиве xor ch,ch mov cl,[numbers+1] xor bh,bh mov bl,cl dec bl mov si,1 ;в si вес разряда n1: mov al,[numbers+2]+bx xor ah,ah cmp al,2dh ;проверим знак числа je otr ;если число отрицательное sub al,30h mul si add [massiv+di],ax mov ax,si mov si,10 mul si mov si,ax dec bx loop n1 jmp n2 otr: neg [massiv+di] ;представим отрицательное число в дополнительном коде n2: ret AscToBin endp BinToAsc PROC ;преобразование числа в строку ;число передается через ax xor si,si add si,5 mov bx,10 push ax cmp ax,0 jnl m1 neg ax m1: cwd idiv bx add dl,30h mov [out_str+si],dl dec si cmp ax,0 jne m1 pop ax cmp ax,0 jge m2 mov [out_str+si],2dh m2: ret BinToAsc ENDP CLEAN PROC mov cx,6 ;очистка буфера вывода xor si,si clear: mov [out_str+si],' ' inc si loop clear ret CLEAN ENDP end Start |