首页 文章

汇编 - 尝试反转字符串,但它在最终字符串上添加了一个额外的字符

提问于
浏览
2

我'm rather new to Assembly (And programming in general, to be honest). I'我试图玩堆栈 . The purpose of this code:

  • 接受一个字符串,限制为80个字符

  • 重新输入输入的字符串

  • 在将每个字符推入堆栈时打印它们

  • 打印从堆栈中弹出的每个字符

  • 打印反转的字符串 .

The code fails on the last step.

如果输入的字符串是“帮助”,它将打印出“pleHe” . 最后一个String中的最后一个字符是原始String的第二个字符 .

请帮我看看我搞砸了!

.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

    Problem

    您将ASCII字符视为WORD而不是字节,因此您最终会反转两个字符:

    当您一次将字符串反转两个字符时,最终会将这些值写入缓冲区:

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

    在每次迭代期间,您的缓冲区如下所示:

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

    所以你最终将额外的e写入缓冲区 . 我假设你的WriteChar循环中没有显示e .

    Solution

    我没有测试过您的代码,所以无法确定,但看起来您需要更改此行:

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

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

    改变这条线也许是一个好主意:

    buffer WORD 81 DUP(0)
    

    所以它使用BYTE代替:

    buffer BYTE 81 DUP(0)
    
  • 0

    这次真是万分感谢!我知道我使用的是WORD而不是BYTE,因为第一部分限制了字符串的大小,而不是使用BYTE . 它正在中间切断弦 .

    所以我没有将缓冲区更改为BYTE .

    也就是说,我尝试进行另一个更改(我认为之前我也曾尝试过),但是仍然遇到编译错误,说明两个操作数必须大小相同 .

    我通过将缓冲区[esi]作为一个字节来修复它!现在它完美无缺!谢谢!

    mov byte ptr buffer[esi], al

相关问题