Зависает программа на TASM - Assembler

Узнай цену своей работы

Формулировка задачи:

Всё работает нормально,но после обращения к макросу программа зависает. Я так думаю,что у меня образовался бесконечный цикл,но не могу понять,как это можно исправить. Программа довольно объёмная,поэтому прикрепил её к вопросу. Задание: Задана строка символов. Посчитать количество символов, ASCII коды которых лежат в заданном интервале. Нахождение ASCII кодов и проверка принадлежности интервалу должны быть оформлено в виде макросов.

Решение задачи: «Зависает программа на TASM»

textual
Листинг программы
.186
masm
model   small
.data
;Сообщения
hello_message       db      10,13,'Hello!$'
info_message        db      10,13,'Enter an ASCII interval to see how much symbols from there.$'
enter_invite        db      10,13,'Enter string of symbols:$'
interval_message1   db      10,13,'Enter start of interval:$'
interval_message2   db      10,13,'Enter end of interval:$'
result_message      db      10,13,'Number of symbols from interval:$'
oshibka             db      10,13,'Interval should be a positive number! Try again!$'
oshibka2            db      10,13,'Interval should be less then 256! Try again!$'
oshibka3            db      10,13,'String cant be empty.$'
result_buf          db      '$$$$'
;Строка
maxsize             equ     51
max                 db      maxsize
string_symb         db      maxsize dup ('$')
;Интервал
granica             equ 256
int_size            equ     4
start_buf           db      int_size
end_buf             db      int_size
 
asci macro                      ;макрос,который проверяет принадлежность ASCII кода к интервалу.
        xor cx, cx
        lea si,string_symb
sravn:  inc si
 
        cmp byte ptr [si],13
        jz vih3
 
        cmp [si],bl
        jb sravn
        
        cmp [si],al
        ja sravn
 
        inc cx
        jmp sravn
        
vih3:
endm        
 
.stack 256h
.code
main    proc
        mov ax,@data
        mov ds,ax
        mov es,ax
        
        mov ah,9
        lea dx,hello_message
        int 21h
        
        mov ah,9
        lea dx,info_message
        int 21h
        
vvd:    mov ah,9
        lea dx,enter_invite
        int 21h
        
        mov ah,0ah              
        lea dx,max
        int 21h 
        
        cmp [max+1],0       ;проверяем длину строки,если она равна 0,то вводим снова.
        je  pust
        jmp dal1
        
pust:   lea dx,oshibka3
        mov ah,9
        int 21h
        jmp vvd
        
dal1:   call zadaem_start
        push ax             ;кидаем начало интервала в стэк.
        call zadaem_konec
        
        xor bx,bx
        pop bx              ;кладём начало интервала в bx,а в ax лежит конец интервала.
        
        cmp bx,ax
        ja smenit
        jmp dal2    
        
smenit:                 ;если начало больше конца,то меняем их местами
        xor cx,cx
        mov cx,bx
        mov bx,ax
        mov ax,cx
        xor cx,cx
        
dal2:   asci
        lea di, result_buf
        mov ax,cx
        call chislo_v_stroku
        
        lea dx,result_message
        mov ah,9
        int 21h
        
        lea dx,result_buf
        mov ah,9
        int 21h
        
        mov ax,4c00h
    int 21h
        
zadaem_start proc
        jmp vvod1
sn1:    lea dx,oshibka2
        mov ah,9
        int 21h
        
vvod1:  mov ah,9
        lea dx,interval_message1
        int 21h
        
        xor al,al
        mov al,10
        mov ah,0ch
        xor di,di
        lea dx,start_buf ;адрес буфера
        int 21h          ;принимаем строку
        
        lea si,start_buf+2 ; берем адрес начала строки
        xor ax,ax
        mov bx,10  ; основание сc
        
povt1:
        mov cl,[si] ; берем символ из буфера
        cmp cl,0dh  ; проверяем не последний ли он
        jz vih1
        
                    ; если символ не последний, то проверяем его на правильность
        cmp cl,'0'  ; если введен неверный символ <0
        jl er1
        cmp cl,'9'  ; если введен неверный символ >9
        ja er1
     
        sub cl,'0' ; делаем из символа число 
        mul bx     ; умножаем на 10
        add ax,cx  ; прибавляем к остальным
        inc si     ; указатель на следующий символ
        jmp povt1  ; повторяем
     
er1:    lea dx,oshibka
        mov ah,09
        int 21h
        jmp vvod1
        
vih1:   cmp [start_buf+1],0 ;сравниваем длину строки с 0,если она равна 0,то вводим строку снова
        je  er1
        cmp ax,granica
        jae sn1
        ret
zadaem_start endp
 
zadaem_konec proc
        jmp vvod2
sn2:    lea dx,oshibka2
        mov ah,9
        int 21h
        
vvod2:  mov ah,9
        lea dx,interval_message2
        int 21h
        
        mov al,10
        mov ah,0ch
        xor di,di
        lea dx,end_buf  ;адрес буфера
        mov end_buf,4   ;коррекция буфера(иначе длина этой строки будет равна числу введённых в прошлую строку символов)
        int 21h         ;принимаем строку
        
        lea si,end_buf+2 ; берем адрес начала строки
        xor ax,ax
        mov bx,10  ; основание сc
povt2:
        mov cl,[si]; берем символ из буфера
        cmp cl,0dh ; проверяем не последний ли он
        jz vih2
        
                   ; если символ не последний, то проверяем его на правильность
        cmp cl,'0' ; если введен неверный символ <0
        jl er2
        cmp cl,'9' ; если введен неверный символ >9
        ja er2
     
        sub cl,'0' ; делаем из символа число 
        mul bx     ; умножаем на 10
        add ax,cx  ; прибавляем к остальным
        inc si     ; указатель на следующий символ
        jmp povt2  ; повторяем
     
er2:   
        mov dx, offset oshibka
        mov ah,09
        int 21h
        jmp vvod2
        
vih2:   cmp [end_buf+1],0
        je er2
        cmp ax,granica
        jae sn2
        ret
zadaem_konec endp
chislo_v_stroku proc
        push cx     ;сохраняем регистры
        push dx
        push bx
        
        mov bx,10   ;основание системы
        xor cx,cx   ;в сх будет количество цифр в десятичном числе
        
del:    xor dx,dx   ;обнуляем dx
        div bx      ;делим число на степени 10
        push dx     ;и сохраняем остаток от деления(коэффициенты при степенях) в стек
        
        inc cx      ;увеличиваем количество символов в числе
        test ax,ax  ;преобразовали все число?
        jnz del     ;если нет, то продолжить
        
preob:  pop ax      ;восстанавливаем остаток от деления
        add al,'0'  ;преобразовываем число в ASCII символ
        stosb       ;сохраняем в буфер
        loop preob  ;все цифры
        
        pop bx      ;восстанавливаем регистры
        pop dx
        pop cx
        ret
chislo_v_stroku endp
main endp
end main

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

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