Data Segment
str1 db 'MADAME','$'
strlen1 dw $-str1 ;calculating the length of the string
strrev db 20 dup(' ')
s1 db 'String is:','$'
NEWLINE DB 10,13,"$"
str_palin db 'String is Palindrome.','$'
str_not_palin db 'String is not Palindrome.','$'
Data Ends
Code Segment
Assume cs:code, ds:data
Begin:
mov ax, data
mov ds, ax
mov es, ax
mov cx, strlen1
add cx, -2
lea si, str1
lea di, strrev
add si, strlen1
add si, -2
mov ah, 09h
lea dx, s1
int 21h
mov ah, 09h
lea dx, str1
int 21h
MOV AH,09H
LEA DX,NEWLINE
INT 21H
L1:
mov al, [si]
mov [di], al
dec si
inc di
loop L1
mov al, [si]
mov [di], al
inc di
mov dl, '$'
mov [di], dl
mov cx, strlen1
Palin_Check:
lea si, str1
lea di, strrev
repe cmpsb
jne Not_Palin
Palin:
mov ah, 09h
lea dx, str_palin
int 21h
jmp Exit
Not_Palin:
mov ah, 09h
lea dx, str_not_palin
int 21h
Exit:
mov ax, 4c00h
int 21h
Code Ends
End Begin
答案 0 :(得分:2)
add cx, -2
)考虑
mov cx, strlen1 add cx, -2 <-- Can be avoided totally
以及
L1: mov al, [si] mov [di], al dec si inc di loop L1 mov al, [si] <-- Should stay inside the loop mov [di], al <-- Should stay inside the loop inc di <-- Should stay inside the loop
由于 strlen1 的定义方式(strlen1 dw $-str1
)add cx, -2
(为什么这不仅仅是sub cx, 2
?)没有给出正确的长度串。你得到的太少了。之后因此,你的 L1 循环必须附加3条额外的指令!
add si, -2
)lea si, str1 add si, strlen1 add si, -2
再次,为什么更喜欢add si, -2
而不是更具可读性sub si, 2
?
由于 strlen1 的定义方式(strlen1 dw $-str1
),add si, strlen1
会使SI
点落后于终止$字符。
减去1会使SI
点点终止$字符,因此后面字符串的最后一个字符。
减去2将使SI
点位于字符串的最后一个字符。
如果您重新定义 strlen1 以使其不包含终止$字符,则上述大部分问题都不会存在。当人们谈论字符串的长度时,他们很少在计数中包含任何终止字符。这样的字符(无论是$还是零)并不是字符串
的 partstrlen1 dw $ - str1 - 1 ;Length of the string
在上下文中查看所有内容:
mov ah, 09h
mov dx, s1
int 21h
mov ah, 09h
mov dx, str1
int 21h
mov ah, 09h
mov dx, NEWLINE
int 21h
cld ;To be absolutely safe
mov cx, strlen1 ;The improved definition! db 'MADAME','$' => 5
mov di, strrev
mov si, str1
add si, cx ;Now points behind the last character ('E')
L1:
dec si
mov al, [si]
stosb ;Equivalent to "mov [di], al" "inc di"
dec cx
jnz L1
mov byte ptr [di], '$'
请注意以下细节:
dec si
指令放在之前阅读[SI]
(我们称之为预先递减),之前可以删除一条指令循环从 L1 开始。lea
替换了每个mov
。结果相同,但代码缩短了1个字节。每一次。loop
dec cx
替换了慢速jnz L1
指令。mov [di], al
inc di
指令替换为仅1个等效指令stosb
。我可以这样做,因为设置了ES
寄存器并且我清除了方向标志(DF)。您的repe cmpsb
也取决于DF = 0。mov byte ptr [di], '$'
替换了编写新$终结符的指令对。