Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1 / МУ_ЭВМ+ПУ_ч1 / 11-МУ_ЭВМ+ПУ-прилA.docx
Скачиваний:
34
Добавлен:
28.05.2015
Размер:
42.8 Кб
Скачать

А.3 Листинг модуля ioproc.Obj

; Модуль IOPROC: Процедуры ввода-вывода

public procnl, procoutnum, procflush, procinch, procinint

iocode segment

assume cs:iocode

;******************************************************

; ВЫВОД НА ЭКРАН

;******************************************************

;======================================================

; Перевод курсора на новую строку экрана

; Обращение: call procnl

; Параметров нет

;-------------------------------------------------------

procnl proc far

push dx

push ax

mov ah,2

mov dl,13 ; CR (курсор на начало строки)

int 21h

mov dl,10 ; LF (курсор на следующую строку)

int 21h

pop ax

pop dx

ret

procnl endp

;============================================================

; Вывод целого числа-слова со знаком или без знака

; Обращение: Call procoutnum

; На входе: ах - выводимое число

; dh - число со знаком (1) или без знака (0)

; dl - ширина поля вывода (>=0)

; (если поле больше, чем надо, то слева добавляются пробелы,

; если меньше - выводится только число)

;----------------------------------------------------------

procoutnum proc far

push bp

mov bp, sp

push ax

push dx

push si

sub sp,6 ; отвести 6 байтов в стеке под число

; учет знака

cmp dh,1 ; вывод со знаком (dh=1)?

jne pon0

cmp ax,0

jge pon0

mov dh,2 ; если вывод со знаком и ах<0,

neg ax ; то dh:=2, ax:=abs(ax)

pon0:push dx ; спасти dh (знак) и dl (ширину)

; запись цифр числа в стек (в обратном порядке)

xor si,si ; si -кол-во цифр в числе

pon1:mov dx,0 ; ax -> (dx,ax)

div cs:ten ; ax=ax div 10; dx= ax mod 10

add dl,'0'

mov [bp-8+si],dl ; цифра -> стек

inc si

or ax,ax

jnz pon1 ; еще не 0

; запись минуса, если есть, в стек

pop dx

cmp dh,2

jne pon2

mov byte ptr [bp-8+si], '-'

inc si

; печать пробелов впереди

pon2:mov dh,0 ; dx =ширина поля вывода

mov ah,2 ; функция 02 прерывания 21h

pon21:cmp dx,si

jle pon3 ; ширина <= длина числа

push dx

mov dl, ' '

int 21h

pop dx

dec dx

jmp pon21

; печать (минуса и) цифр

pon3:dec si

mov dl,[bp-8+si]

int 21h

or si,si

jnz pon3

; выход из процедуры

add sp,6

pop si

pop dx

pop ax

pop bp

ret

ten dw 10

procoutnum endp

;*******************************************************

; ВВОД С КЛАВИАТУРЫ

;*******************************************************

;буфер ввода с клавиатуры (для работы с функцией 0ah)

maxb db 128 ; макс. размер буфера ввода

sizeb db 0 ; число введенных символов в буфере

buf db 128 dup(?) ; сам буфер ввода

posb db 0 ; номер последнего считанного символа

; из буфера

;========================================================

;вспомогательная процедура ввода строки символов

;(включая ENTER) в буфер buf (ввод без приглашения)

;--------------------------------------------------------

readbuf proc near

push ax

push dx

push ds

mov dx,cs

mov ds,dx

lea dx,buf-2 ; ds:dx - адрес buf[-2]

mov ah,0ah ; ввод строки в буфер (включая ENTER)

int 21h

call procnl ; курсор на новую строку экрана

inc cs:sizeb ; в длине учесть ENTER

mov cs:posb,0 ; сколько символов уже считано из buf

pop ds

pop dx

pop ax

ret

readbuf endp

;===========================================================

;Очистка буфера ввода с клавиатуры

;Обращение: call procflush

;Параметров нет

;-----------------------------------------------------------

procflush proc far

push ax

mov cs:sizeb,0 ; очистка буфера buf

mov cs:posb,0

mov ah,0ch ;очистка DOS-буфера

mov al,0

int 21h

pop ax

ret

procflush endp

;============================================================

; Ввод символа (с пропуском или без пропуска ENTER)

; Обращение: call procinch

; На входе : ENTER -пропустить (0) или выдать как символ (1)

; На выходе: al - введенный символ (ah не меняется)

;------------------------------------------------------------

procinch proc far

push bx

princh1:

mov bl,cs:posb ; номер последнего считанного символа

inc bl ; следующий номер

cmp bl,cs:sizeb ; не последний символ буфера?

jb princh2

jne princh10 ; буфер не считан до конца?

cmp al, 0 ; считывать ли конец строки (ENTER)?

jne princh2

princh10:

call readbuf ; доввод в буфер

jmp princh1 ; повторить

princh2:

mov cs:posb,bl ;запомнить номер считываемого символа

mov bh,0

mov al,cs:buf[bx-1] ; al:=символ

pop bx

ret

procinch endp

;===============================================================

;Ввод целого числа (со знаком и без) размером в слово

; Обращение: call procinint

; На входе - нет

; На выходе: ax - введенное число

;---------------------------------------------------------------

procinint proc far

push bx

push cx

push dx

;пропуск пробелов и концов строк вначале

prinint1:

mov al,0

call procinch ; al- очередной символ (с пропуском ENTER)

cmp al,' ' ; пробел?

je prinint1

; проверка на знак

mov dx,0 ; dx-вводимое число

mov cx,0 ; ch=0 - нет цифры, cl=0 - плюс

cmp al,'+'

je prinint2

cmp al,'-'

jne prinint3

mov cl,1 ; cl=1 - минус

; цикл по цифрам

prinint2:

mov al,1

call procinch ; al - очередной символ (ENTER - символ)

prinint3: ; проверка на цифру

cmp al,'9'

ja prinint4 ; >'9' ?

sub al,'0'

jb prinint4 ; <'0' ?

mov ch,1 ; ch=1 - есть цифра

mov ah,0

mov bx,ax ; bx - цифра как число

mov ax,dx ; ax - предыдущее число

mul cs:prten ; *10

jc provfl ; >FFFFh (dx<>0) ->переполнение

add ax,bx ; +цифра

jc provfl

mov dx,ax ; спасти число в dx

jmp prinint2 ; к след символу

; кончились цифры (число в dx)

prinint4:

mov ax,dx

cmp ch,1 ; были цифры?

jne prnodig

cmp cl,1 ; был минус?

jne prinint5

cmp ax,8000h ; модуль отр числа > 8000h ?

ja provfl

neg ax ; взять с минусом

prinint5:

pop dx ; выход

pop cx

pop bx

ret

prten dw 10

;----------реакция на ошибки при вводе числа

provfl: lea cx, prmsgovfl ; переполнение

jmp prerr

prnodig: lea cx,prmsgnodig ; нет цифр

prerr: push cs ; печать сообщения об ошибке

pop ds ; ds=cs

lea dx,prmsg

mov ah,9 ; outstr

int 21h

mov dx,cx

mov ah,9 ; outstr

int 21h

call procnl

mov ah,4ch

int 21h

prmsg db 'Ошибка при вводе числа: ','$'

prmsgovfl db 'переполнение','$'

prmsgnodig db 'нет цифры','$'

procinint endp

iocode ends

end ; конец модуля ioproc

104

Соседние файлы в папке МУ_ЭВМ+ПУ_ч1