В инструкции говорится о ReadString :
Считывает строку из ненулевых символов ECX из стандартного ввода, останавливаясь, когда пользователь нажимает клавишу Enter.
Нулевой байт сохраняется после ввода символов , но символы возврата каретки и перевода строки не помещаются в буфер.
ECX всегда должен быть меньше размера буфера (никогда не равняется размеру буфера), поскольку нулевой байт может быть (ECX + 1) -ым сохраненным символом.
После этого ясно, что вам нужно увеличить буфер:
buffer BYTE MaxLength + 1 DUP (0)
Если вы указали ECX=MaxLength
, то вы не можете получить ввод, который длиннее MaxLength символов, и, следовательно, нет реальной необходимости проверять такое условие.(*)
Если пользователь нажимает клавишу enter без предшествующих символов, то ReadString вернется с EAX=0
.Проверьте это и перейдите к своему последнему сообщению.
Большая ошибка, когда вы написали loop L1
.Инструкция loop
работает с регистром ECX
для выполнения известного числа итераций.Ваша программа должна просто вернуться наверх без каких-либо условий.Используйте jmp L1
.
Лучше всего, если вы будете держать вещи логически вместе.Не смешивайте call PromptForInput
с call ReadString
и его параметрами.Можете ли вы быть уверены, что PromptForInput не изменится EDX
или ECX
?
L1: call PromptForInput
mov edx, OFFSET buffer
mov ecx, MaxLength
call ReadString ; -> EAX
test eax, eax
jz L2 ; Exit
call ReverseString ; Is this working fine?
call CaseChange
mov edx, OFFSET buffer
call WriteString ; Printing the result
jmp L1
L2:
mov edx, OFFSET prompt3
call WriteString ; Final message
exit
cmp dl, 'A'
jl L3
The *Процедура 1050 * ChangeCase должна пройти всю строку, но вы уйдете, как только наткнетесь на байт меньше 65. Пожалуйста, используйте условие unsigned при работе с кодами ASCII [0,255].
xor dl,32
Вы фактически не записываете какие-либо изменения в строковую память.
cmp dl,'z'
Вы не действуете на этомсравнить.
Если все, что вам нужно сохранить, это 1 регистр, не используйте pushad
и popad
.
CaseChange PROC
push esi
mov esi, OFFSET buffer
L1:
lodsb
test al, al ; End of string ?
jz L2
or al, 32 ; If "A".."Z" Then "a".."z"
cmp al, 'a'
jb L1
cmp al, 'z'
ja L1
xor byte ptr [esi-1], 32 ; Change case IN string memory
jmp L1
L2:
pop esi
ret
CaseChange ENDP
(*) Есливы хотите наложить эту ошибку «Строка не может быть длиннее 20 символов», затем определить гораздо больший буфер и позволить ReadString вернуть более 20 символов, чтобы вы могли вернуться назад в программе:
buffer BYTE 99 + 1 DUP (0)
...
L1: call PromptForInput
mov edx, OFFSET buffer
mov ecx, 99
call ReadString ; -> EAX
cmp eax, 20
ja L1
test eax, eax
jz L2 ; Exit
Последний совет - убедиться, что ReverseString и CaseChange в порядке, проверив их независимо:
call ReverseString
;;;call CaseChange
mov edx, OFFSET buffer
call WriteString ; Printing the result
и более поздние
;;;call ReverseString
call CaseChange
mov edx, OFFSET buffer
call WriteString ; Printing the result
и только потом
call ReverseString
call CaseChange
mov edx, OFFSET buffer
call WriteString ; Printing the result