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