Чтение строки и расчет длины работают нормально.Но при сравнении символов строки она не работает для первых двух символов.
Как оказалось, это именно та часть сравнения, которая подходит!Ваши проблемы начинаются с ввода и существуют, потому что вы не поняли, что делает вопросительный знак в программировании на ассемблере.
input db 10,?
length db ?
count db ?
Во всех этих строках знак вопроса ? представляет один байт, который большинство, если не все ассемблеры, инициализируют нулевым значением 0 .Таким образом, вы получите:
input db 10, 0
length db 0
count db 0
Это хорошо для длина и количество , но не так для input , который долженбыть входным буфером для буферизированной входной функции DOS 0Ah .У вас нет необходимого места для хранения на самом деле.Это память на длина , count и т. Д., Которая ошибочно перезаписывается!
Решение - input db 10, 0, 10 dup (?)
.Это позволяет вводить 9 символов.Почему 9?Поскольку DOS всегда добавляет возврат каретки 13 к входу, а для возврата каретки также требуется байт в этом 10-байтовом пространстве хранения, определяемом 10 dup (?)
.
Также этот возврат каретки объясняет, почемуВаш расчет длины не удастся.Вы ищете «$», когда вы должны искать код ASCII 13.
Конечно, вычисление длины является излишним, так как DOS уже проинформировал вас об этом.2-й байт структуры ввода равен длины.
mov cx, 0
mov cl, [input+1] ; length
Все вместе:
.DATA
input db 10, 0, 10 dup (?)
count db ?
.CODE
.STARTUP
;reading string
mov dx, offset input
mov ah, 0Ah
int 21h
;checking for vowels
xor cx, cx ; Also clears the CX register like `mov cx, 0`
mov count, cl ; Count = 0
mov si, offset input+2
mov cl, [si-1] ; length is 2nd byte
counting:
cmp [si], 'a'
je count1
cmp [si], 'e'
je count1
cmp [si], 'i'
je count1
cmp [si], 'o'
je count1
cmp [si], 'u'
je count1
inc si
loop counting
cmp cl, 0 \ You can replace these 2 by
je exit / a single `jmp exit`
count1:
inc count
inc si
loop counting
exit:
.EXIT
Лучшее решение
- без использования медленной инструкции
loop
- минимизация доступа к памяти
- с использованием строковых примитивов, таких как
lodsb
- , при сбое, если строка пуста!
- минимизация количества прыжков вокруг
представлена здесь:
;checking for vowels
cld ; For completeness because `lodsb` depends on it
mov si, offset input+2
mov dl, -1
vowel:
inc dl
other:
lodsb ; This is `mov al, [si]` followed by `inc si`
cmp al, 'a'
je vowel
cmp al, 'e'
je vowel
cmp al, 'i'
je vowel
cmp al, 'o'
je vowel
cmp al, 'u'
je vowel
cmp al, 13
jne other
mov count, dl