Asamblea - Tratando de cadena inversa, pero añade un carácter adicional en la cadena final

StackOverflow https://stackoverflow.com/questions/2308057

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 
¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top