Другие языки программирования и технологии

assembler tasm - в чем ошибка?

задача: вычитываем строчку, и каждое число, которое там находим, меняем на слово, т. е. asf5sd3 -> asffivesdthree (числа 0-9 = от "zero" до "nine") (ну и+ считаем сколько елементов в веденной строчке)
есть идея считав строчку просто делать cmp с каждым елементом, если это не число вывести его на экран, а если число выводить название числа как сообщение
написан такой код, но в нем есть ошибка. никак не могу найти. помогите, пожалуйста. как понимаю что-то в search не так.

.model small
.stack 100h
.data
msg db "Entry: $"
msg2 db "Character count: $"
sk0 db "zero$"
sk1 db "one$"
sk2 db "two$"
sk3 db "three$"
sk4 db "four$"
sk5 db "five$"
sk6 db "six$"
sk7 db "seven$"
sk8 db "eight$"
sk9 db "nine$"
string db 255, ?,256 dup ('$')
enteris db 13,10,'$'

.code
Start:
mov ax, @data
mov ds, ax

mov ah, 9
mov dx, offset msg
int 21h

mov ah, 0Ah
mov dx, offset string
int 21h

mov ah, 9
mov dx, offset enteris
int 21h

Search: ;ищет где цифры - если не цифра просто выводит, если цифра выводит нужное слово
mov si, offset string+2
mov ax,[ds:si]

cmp ax, 39h
ja Output1
cmp ax, 30h
jb Outbut1
cmp ax, 30h
je Zero
cmp ax, 31h
je One
cmp ax, 32h
je Two
cmp ax, 33h
je Three
cmp ax, 34h
je Four
cmp ax, 35h
je Five
cmp ax, 36h
je Six
cmp ax, 37h
je Seven
cmp ax, 38h
je Eight
cmp ax, 39h
je Nine
cmp ax, "$"
je Output

Output1:
mov ah,9
mov dx, ax
int 21h
inc si
jmp Search

Zero:
mov ah,9
mov dx, offset sk0
int 21h
inc si
jmp Search

One:
mov ah,9
mov dx, offset sk1
int 21h
inc si
jmp Search

Two:
mov ah,9
mov dx, offset sk2
int 21h
inc si
jmp Search

Three:
mov ah,9
mov dx, offset sk3
int 21h
inc si
jmp Search

Four:
mov ah,9
mov dx, offset sk4
int 21h
inc si
jmp Search

Five:
mov ah,9
mov dx, offset sk5
int 21h
inc si
jmp Search

Six:
mov ah,9
mov dx, offset sk6
int 21h
inc si
jmp Search

Seven:
mov ah,9
mov dx, offset sk7
int 21h
inc si
jmp Search

Eight:
mov ah,9
mov dx, offset sk8
int 21h
inc si
jmp Search

Nine:
mov ah,9
mov dx, offset sk9
int 21h
inc si
jmp Search

Output:
mov ah, 9
mov dx, offset msg2
int 21h

lea dx,msg2
mov ah,9
int 21h

mov al,string+1
call Print

Exit:
mov ah, 4Ch
int 21h

Print proc
xor cx,cx
mov bl,10
Prepare:
xor ah,ah
div bl
add ah,'0'
push ax
inc cx
or al,al
jnz Prepare
PutChar:
pop ax
mov al,ah
int 29h
loop PutChar
ret
Print endp

END start
Код программы очень большой, поэтому привожу только фрагменты с ошибками.

...
Search:
    mov si, offset string+2; загрузка адреса начала введённой строки
;Чтобы адрес на каждой итерации цикла не устанавливался снова на
;начало строки, переход следует делать сюда, а не на Search (это причина зависания)
Search1:
;Символ имеет размер 1 байт, поэтому везде ax нужно заменить на al
    mov al,[si]; и не нужно делать замену сегмента
;Проверку на окончание строки следует делать до всех прочих проверок
    cmp al, 0Dh; Строка, введённая функцией 0Ah, оканчивается кодом 0Dh, а не "долларом"
    jne Tests ; Так нелогично приходится делать, потому что у процессора i8086 нет
    jmp Output ; близких условных переходов (near), только короткие (short +/- 127 байт)
; чтобы сделать красивее, можно или компилировать для процессора i80386 и старше, или
; использовать директиву jumps, тогда TASM, когда метка перехода расположена дальше
; 127 байт, сам будет заменять их (короткие переходы) на подобную пару jncc и jmp
Tests:
    cmp al, 30h
    je Zero
    cmp al, 31h
    je One
    cmp al, 32h
    je Two
    cmp al, 33h
    je Three
    cmp al, 34h
    je Four
    cmp al, 35h
    je Five
    cmp al, 36h
    je Six
    cmp al, 37h
    je Seven
    cmp al, 38h
    je Eight
    cmp al, 39h
    je Nine
; Выброшены проверки больше 9 и меньше 0, так как если выше ни одно условие равенства
; не выполнится, то всё равно выполнение программы дойдёт до этой точки

Output1:
    mov ah,2; вывод одного символа - это функция 2
    mov dl, [si]; и выводит она символ, записанный в регистр dl
    int 21h
;Вместо предыдущих 3 строк можно написать просто int 29h - вывод символа из al
    inc si
    jmp Search1; Переход должен быть на команду после загрузки адреса начала строки

Zero:
    mov ah,9
    mov dx, offset sk0
    int 21h
    inc si
    jmp Search1; Здесь тоже метку перехода нужно изменить. И так для каждой цифры

...

Output:
    mov ah, 9
    mov dx, offset enteris; Здесь нужен перевод строки
    int 21h

    lea dx,msg2
    mov ah,9
    int 21h

    mov al,string+1
    call Print
...
Ильдар Саттаров
Ильдар Саттаров
51 590
Лучший ответ
давно я с ассемблером не работал.. . а что показывает в итоге? или программа зацикливается?