Выделить из строки, введенной с клавиатуры, десятичные числа, заключенные между символами | - Assembler
Формулировка задачи:
Выделить из строки, введенной с клавиатуры, десятичные числа, заключенные между символами |. Найти сумму найденных чисел. Результат отразить числом, представленным в десятичной системе счисления. Вывести результат требуется зеленым цветом в центре экрана.
(разработать в ассемблере, ну и чтоб работала)
Решение задачи: «Выделить из строки, введенной с клавиатуры, десятичные числа, заключенные между символами |»
textual
Листинг программы
;Вариант№1 ;Выделить из строки, введенной с клавиатуры, десятичные числа, ;заключенные между символами |. Найти сумму найденных чисел. ;Результат отразить числом, представленным в десятичной системе счисления. ;Вывести результат требуется зеленым цветом в центре экрана. .286 .model small .stack 100h .data msg db 'Enter string',0Dh,0Ah,'$' result dw 0 ;результат сложения найденных чисел vmode dw 0 ;переменная видеорежима len dw ? ;длина строки-числа для вывода buff db 255,?,255 ;буфер для ввода .code start: mov ax,@data mov ds,ax mov es,ax mov ah,9 mov dx,offset msg int 21h ;вывести приглашение ввода строки mov ah,0Ah mov dx,offset buff int 21h ;буферизированный ввод строки ;запись начинаеться по адресу buff+2 ;по адресу buff+1 записываеться число введенных символов mov si,offset buff+2 call calc ;вывзвать процедуру нахождения чисел и их сложения mov ax,[result] ;передать результат для вывода mov si,offset buff+2 ;буфер для записи call HexToStr ;вызвать процедуру конвертации числа в символы call saveMode ;сохранить текущий видеорежим call scrInit ;перевести в текстовый видеорежим mov ah,2h ;цвет зеленый на черный mov cx,[len] ;число символов для вывода mov di,12*80*2+70 ;адрес середины окна в видеопамяти ; (12 строк по 80 символов * 2 байта +35*2 байт до середины) mov si,offset buff+2 ;адрес строки для вывода @out: mov al,[si] ;взять символ stosw ;провести запись в ES:DI символа в AL inc si ;смещение на сл.символ loop @out mov ah,1 ;ожидать нажатие клавиши int 21h call setOldMode ;восстановить предыдущий режим ;выход из программы exit: mov ah,4ch int 21h ;преобразование числа в строку десятичных цифр ;на входе AX=число для преобразования ;SI=адрес массива для записи символов HexToStr proc mov bx,10 ;делитель xor cx,cx ;счетчик символов @L4: xor dx,dx ;DX=0 div bx ;разделить AX на 10 add dl,'0' ;преобразовать цифру в символ push dx ;сохранить в стек inc cx ;увеличить счетчик полученных символов cmp ax,0 ;сравнить AX на 0 jne @L4 ;продолжить если не 0 mov [len],cx ;сохранить число получ.цифр ;сохраняли в стек,потому что находяться сначало младшие разряды числа ;потом достаем из стека в обратном порядке записывая в массив со старших @L5: pop dx ;достать из стека цифру mov [si],dl ;сохранить в массив inc si ;изменить адрес на 1 loop @L5 ;продолжать цикл Ret HexToStr EndP ;процедура анализа строки ;на входе SI=адрес строки calc proc xor cx,cx ; mov cl,buff[1] ;CX=длина строки @L: mov di,si ;для сканирования передать адрес строки в DI call scan ;вызвать процедуру сканирования на символ "|" cmp cx,0 ;сравнить число оставшихся символов je extcalc ;если 0,на выход mov si,di ;записать адрес найденного "|' в SI и передать ;процедуре нахождения числа call getnum ;вызвать процедуру нахождения числа cmp cx,0 ;сравнить число оставшихся символов jne @L ;если не 0,на продолжать extcalc: ret calc endp ;процедура поиска числа ;SI=адрес строки getnum proc mov bx,10 ;множитель = 10 xor ax,ax ;регистры в 0 xor dx,dx @L1: cmp byte ptr [si],'|' ;сравнить с символом | jne next ;перейти если не равно add result,ax ;иначе записать в результат jmp extget ;и выйти ;цикл перевода символов в число next: cmp cx,0 ;сравнить остаток длины строки на 0 je extget ;выйти если равно cmp byte ptr [si],'0' ;сраувнить символ jb extget ;если меньше то заключено не число cmp byte ptr [si],'9' ;сравнить с символом 9 ja extget ;если больше то не число [B]mul bx ;умножить текущий результат в AX на 10 mov dl,[si] ;поместить символ sub dl,'0' ;преобразовать в цифру add ax,dx ;прибавить цифру[/B] inc si ;увеличить смещение на сл.символ в строке dec cx ;отнять от длины строки 1 jmp @L1 ;перейти продолжая цикл extget: inc si ;увеличть адрес на 1,на символ за '|' Ret getnum EndP ;процедура сканирования строки ;на входе DI=адрес строки ;CX=длина строки ;на выходе DI=адрес символа за '|' scan proc mov al,'|' ;символ для поиска repne scasb ;повторять пока не найден или CX не равен 0 Ret scan EndP ;сохранение текущего видеорежима saveMode proc mov ah,0fh ;ф-ция сохранения текущего видеорежима int 10h mov byte ptr vmode[0],al ;поместить номер текущего режима в переменную Ret saveMode EndP ;восстановить видеорежим setOldMode proc mov ax,[vmode] ;восстановить видеорежим int 10h Ret setOldMode EndP ;очистить экран консоли clrscr proc mov ax, 03 int 10h Ret clrscr EndP ;инициализация текстового видеорежима 80x25 scrInit proc mov bh,0 ;номер видеостраницы mov ax,3 ;текстовый видеорежим int 10h ;установить push 0B800h pop es ;адрес видеопамяти в ES=0B800h mov dx,1900h ;номер строки 25 mov ah,2 int 10h ;убрать курсор за пределы экрана ret scrInit endp end start