Assembléia - tentando reverter string, mas adiciona um caractere extra na string final
Pergunta
Sou bastante novo na montagem (e programação em geral, para ser sincero). Estou tentando brincar com a pilha.O objetivo deste código:
- Pegue uma string, limitada a 80 caracteres
- Reimprimir a string como inserida
- Imprima cada caractere enquanto é empurrado para a pilha
- Imprima cada caractere enquanto ele é retirado da pilha
- Imprima a string invertida.
O código falha na última etapa.
Se a string inserida for "Ajuda", ela imprimirá "Plehe". O último caractere na sequência final é o segundo caractere da string original.
Por favor me ajude a ver onde estou bagunçando!
.data buffer WORD 81 DUP(0) byteCount WORD ? .code main PROC call Clrscr ;Clear screen RS: mov edx, OFFSET buffer ;Move String to edx mov cl, [SIZEOF buffer]-1 ;Set loop counter to (size of buffer) -1 call ReadString ;Read a User's String mov byteCount, ax ;Move the size of User's String to byteCount cmp byteCount, 80 ;Compare byteCount with 80 ja RS ;If byteCount is greater then 80, ask for another String call WriteString ;Write User's String to screen call Crlf ;New Line call reverseIt ;Reverse order of String exit reverseIt PROC movzx ecx, byteCount ;Set Loop1 Counter to size of String mov esi, 0 ;Zero out ESI L1: ;Loop1 - Pushes String into Stack one character at a time movzx eax, buffer[esi] ;Dereference buffer and place in eax call Crlf ;New Line call WriteChar ;Print current character to screen push eax ;Push current character to stack inc esi ;Move to next character loop L1 call Crlf movzx ecx, byteCount ;Set Loop2 Counter to size of String mov esi, 0 ;Zero out ESI L2: ;Loop2 - Pops Characters back into String in reverse order pop eax ;Retrieve character from top of stack call Crlf ;New Line call WriteChar ;Print current character to screen mov buffer[esi], ax ;Writes character to String inc esi ;Increase esi loop L2 call Crlf ;New Line call Crlf ;New Line mov edx, OFFSET buffer ;Move String to edx for WriteString call WriteString ;Prints String to Screen call Crlf ;New Line ret ;Return to main reverseIt ENDP main ENDP END main
Solução
Problema
Você está tratando seus caracteres ASCII como palavras em vez de bytes, então acaba revertendo dois caracteres por vez:
Ao reverter a string dois caracteres por vez, você acaba escrevendo esses valores no buffer:
esi+0: p-
esi+1: lp
esi+2: el
esi+3: He
Durante cada iteração, seu buffer se parece com o seguinte:
Help--
p-lp--
plpp--
plel--
pleHe-
Então você acaba escrevendo esse E extra para o buffer. Presumo que o E não apareça em seu loop de Writechar.
Solução
Eu não testei seu código, então não tenho certeza, mas parece que você precisa alterar esta linha:
mov buffer[esi], ax ;Writes character to String
para
mov ptr byte buffer[esi], al ;Writes character to String
Provavelmente é uma boa ideia mudar essa linha também:
buffer WORD 81 DUP(0)
Então ele usa bytes:
buffer BYTE 81 DUP(0)
Outras dicas
Obrigado por isso! Eu sabia que estava usando palavras em vez de bytes porque a primeira parte, onde limita o tamanho da corda, não estava trabalhando com bytes. Estava cortando a corda no meio.
Então eu não mudei de buffer para byte.
Dito isto, tentei fazer a outra mudança (que acho que já havia tentado antes), mas continuei recebendo um erro de compilação afirmando que ambos os operandos devem ter o mesmo tamanho.
Eu consertei isso lançando buffer [ESI] como um byte! Agora funciona perfeitamente! Obrigado!
mov byte ptr buffer[esi], al