Asamblea - Tratando de cadena inversa, pero añade un carácter adicional en la cadena final
Pregunta
Soy bastante nuevo en la Asamblea (y la programación en general, para ser honesto). Estoy tratando de jugar con la pila. El propósito de este código:
- Tome en una cadena, limitado a 80 caracteres
- Reimpresión la cadena como entrado
- Imprimir cada personaje a medida que se desplaza a la pila
- Imprimir los caracteres que se extrae de la pila
- Imprimir la cadena invertidos.
El código de error en el último paso.
Si la cadena introducida es "ayuda", se imprimirá "pleHe". El último carácter de la cadena final es el segundo carácter de la cadena original.
Por favor, ayuda a ver dónde estoy arruinando a!
.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
Solución
Problema:
se está tratando el caracteres ASCII como palabras en lugar de bytes, por lo que terminan revirtiendo dos caracteres a la vez:
Cuando se invierte la cadena de dos caracteres a la vez, se termina de escribir estos valores a la memoria intermedia:
esi+0: p-
esi+1: lp
esi+2: el
esi+3: He
Durante cada iteración su apariencia tampón como este:
Help--
p-lp--
plpp--
plel--
pleHe-
Así que terminan escribiendo ese extra de correo a la memoria intermedia. Asumo la dirección no aparece en su bucle WriteChar.
Solución
No he probado el código por lo que no se puede saber a ciencia cierta, pero parece que es necesario cambiar esta línea:
mov buffer[esi], ax ;Writes character to String
a
mov ptr byte buffer[esi], al ;Writes character to String
Es probablemente una buena idea para cambiar esta línea también:
buffer WORD 81 DUP(0)
por lo que utiliza bytes en lugar:
buffer BYTE 81 DUP(0)
Otros consejos
Gracias por esto! Yo sabía que estaba usando palabras en lugar de bytes porque la primera parte, donde se limita el tamaño de la cadena, no funcionaba con bytes. Se estaba cortando la cuerda en el medio.
Así que no cambió el tampón a BYTE.
Dicho esto, he intentado hacer que el otro cambio (que creo que me había probado antes, también), pero cuidado para conseguir un error de compilación que indica que ambos operandos deben ser del mismo tamaño.
Me fijado por este buffer de fundición [ESI] como un byte! Ahora funciona perfectamente! Gracias!
mov byte ptr buffer[esi], al