Зависает программа на 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