Выделить из строки, введенной с клавиатуры, десятичные числа, заключенные между символами | - 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

Оцени полезность:

9   голосов , оценка 3.889 из 5
Похожие ответы