Сборка - Попытка перевернуть строку, но она добавляет дополнительный символ в окончательной строке - PullRequest
2 голосов
/ 22 февраля 2010

Я довольно новичок в сборке (и, если честно, программирование). Я пытаюсь играть со стеком. Назначение этого кода:

  • Взять строку, ограничено 80 символами
  • Перепечатайте строку как введено
  • Печать каждого символа по мере его помещения в стек
  • Печатать каждый символ, как только он извлечен из стека
  • Распечатать обратную строку.

Код не выполняется на последнем шаге.

Если введенная строка «Справка», она выведет «pleHe». Последний символ в последней строке является вторым символом исходной строки.

Пожалуйста, помогите мне увидеть, где я все испортил!

.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 

Ответы [ 2 ]

5 голосов
/ 22 февраля 2010

Задача

Вы рассматриваете свои символы ASCII как слова, а не как байты, поэтому в итоге вы меняете два символа одновременно:

Когда вы переворачиваете строку по два символа за раз, вы в конечном итоге записываете эти значения в буфер:

esi+0: p-
esi+1: lp
esi+2: el
esi+3: He

Во время каждой итерации ваш буфер выглядит так:

Help--
p-lp--
plpp--
plel--
pleHe-

Итак, вы заканчиваете тем, что записываете эту дополнительную е в буфер. Я предполагаю, что e не появляется в вашем цикле WriteChar.

Решение

Я не проверял ваш код, поэтому не могу знать наверняка, но, похоже, вам нужно изменить эту строку:

mov buffer[esi], ax         ;Writes character to String

до

mov ptr byte buffer[esi], al         ;Writes character to String

Вероятно, неплохо бы изменить и эту строку:

buffer WORD 81 DUP(0)

, поэтому вместо него используются байты:

buffer BYTE 81 DUP(0)
0 голосов
/ 22 февраля 2010

Спасибо вам за это! Я знал, что я использую WORD вместо BYTE, потому что первая часть, где он ограничивает размер строки, не работает с BYTE. Он обрезал струну посередине.

Поэтому я не изменил буфер на BYTE.

Тем не менее, я попытался внести другое изменение (которое, как мне кажется, я пытался и раньше), но продолжал получать ошибку компиляции, утверждая, что оба операнда должны быть одинакового размера.

Я исправил это путем приведения буфера [esi] в качестве байта! Теперь это работает отлично! Спасибо!

mov byte ptr buffer[esi], al

...