在程序集 8086 中反转字符串的问题

Problem in reversing a string in assembly 8086

我需要反转程序集 8086 中的给定字符串。我编写了一个应该可以工作的代码,但我得到了输出

'MAGSM$HIMI

而不是

MAGSHIMIM

我不知道代码有什么问题。我怀疑是“$”引起了问题,但我不知道。

我的代码:

 org 100h

jmp main    
    chrs db  'M','I','M','I','H','S','G','A','M', '$'


main:
    mov bp, sp

    mov ax,offset chrs
    call print_ax_str 
    mov ax, offset chrs
    push ax
    push 9
    call reverse
    PRINTN ;new line
    mov ax,offset chrs
    call print_ax_str 

    jmp stop

reverse proc
    ; First save the old BP  
    push bp 
    ; Now establish new BP 
    mov bp, sp  
    ;make space for 2 local variables
    sub sp, 4

    mov dx, [bp+6]
    mov bx, [bp+4] ;bx = 9
    dec bx         ;bx = 8
    add dx, bx ; dx = dx + 8    
    mov di, dx 
    mov SI, [bp+6] 
    mov cx, 4
    L1: 
    mov dx, [si]    
    xchg ax, [di]  
    mov [si], ax
    mov [di], dx 
    inc si        ;si--
    dec di        ;di++

    loop L1

    mov sp, bp 
    ; Restore OLD BP 
    pop bp
    retn 4 
reverse endp


stop:
    mov ah, 0 
    int 16h 
    ret

include magshimim.inc
chrs db  'M','I','M','I','H','S','G','A','M', '$'
 ...
L1: 
 mov dx, [si]    
 xchg ax, [di]  
 mov [si], ax
 mov [di], dx 
 inc si        ;si--
 dec di        ;di++
 loop L1

这里最大的问题是您的 chrs 字符串包含字节,但您的逆向程序使用单词(2 个字节)。

看着这个循环,我怀疑你混合了 2 个解决反转问题的方法。 xchg ax, [di] 指令说明了这一点。

解决方案 1 使用 MOV

L1: 
 mov dl, [si]    
 mov al, [di]  
 mov [si], al
 mov [di], dl 
 inc si        ;si++
 dec di        ;di--
 loop L1

解决方案 2 使用 XCHG

L1: 
 mov dl, [si]    
 xchg dl, [di]  
 mov [si], dl
 inc si        ;si++
 dec di        ;di--
 loop L1

请注意您代码中的注释是错误的。增加 SI 对应 "si++"。同样递减 DI 对应 "di--".


由于您将字符串的长度传递给过程并拥有基于它的指针,因此您还应该将循环计数器基于它而不是通过 mov cx, 4 使用固定计数 4。

 mov cx, [bp+4]   ;SLen
 shr cx, 1        ;SLen/2
L1:

进行一些额外的清理:

reverse proc
 push bp 
 mov  bp, sp
 mov  cx, [bp+4] ;SLen
 mov  si, [bp+6]
 mov  di, si
 add  di, cx
 dec  di
 shr  cx, 1      ;SLen/2
L1: 
 mov  dl, [si]    
 mov  al, [di]  
 mov  [si], al
 mov  [di], dl 
 inc  si        ;si++
 dec  di        ;di--
 loop L1
 pop  bp
 retn 4 
reverse endp