反向装配8086中的字符串时出现问题

时间:2018-11-23 21:09:30

标签: string assembly reverse x86-16

我需要在程序集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

1 个答案:

答案 0 :(得分:3)

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个字节)。

看着这个循环,我怀疑您对反转问题混合了两种解决方案。 xchg ax, [di]指令说明了这一点。

使用MOV

的解决方案1
L1: 
 mov dl, [si]    
 mov al, [di]  
 mov [si], al
 mov [di], dl 
 inc si        ;si++
 dec di        ;di--
 loop L1

使用XCHG

的解决方案2
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