Зависает программа на 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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д