String 汇编语言x86中的字符串反转
我是汇编语言的新手,我有一段代码,假设它可以反转字符串的长度,现在我知道我已经接近了,但不管是什么原因,程序总是在我身上崩溃。问题出在strev进程中。我在这个代码中做错了什么String 汇编语言x86中的字符串反转,string,assembly,x86,reverse,irvine32,String,Assembly,X86,Reverse,Irvine32,我是汇编语言的新手,我有一段代码,假设它可以反转字符串的长度,现在我知道我已经接近了,但不管是什么原因,程序总是在我身上崩溃。问题出在strev进程中。我在这个代码中做错了什么 INCLUDE Irvine32.inc .data prompt BYTE "Enter String: ", 0 response BYTE 50 DUP(0) message BYTE " Message entered. ",0 .code swap MACRO a,b
INCLUDE Irvine32.inc
.data
prompt BYTE "Enter String: ", 0
response BYTE 50 DUP(0)
message BYTE " Message entered. ",0
.code
swap MACRO a,b
xor a,b
xor b,a
xor a,b
endM
STRQRY PROC
push ebp
mov ebp, esp
push edx
push ecx
mov edx, [ebp+8]
call writestring
mov ecx, SIZEOF response
mov edx, OFFSET response
call readstring
pop ecx
pop edx
pop ebp
ret 4
STRQRY ENDP
STRLEN PROC
push ebp
mov ebp, esp
push ebx
push ecx
mov edx,[ebp+16]
mov eax, 0
counter:
mov cl,[edx+eax]
cmp cl, 0
JE done
inc eax
jmp counter
done:
pop ecx
pop ebx
pop ebp
ret 4
STRLEN ENDP
STRREV proc
push ebp
mov ebp, esp
push OFFSET response
call STRLEN
mov edx, [ebp+8]
mov esi, 0
dec eax
reverseloop:
mov ah, [edx+esi]
mov al, [edx+eax]
swap ah, al
mov [edx+esi],ah
mov [edx+eax],al
inc esi
dec eax
cmp esi, eax
jb reverseloop
ja finish
finish:
pop ebp
ret 4
STRREV endp
main PROC
push OFFSET prompt
call STRQRY
call writedec
mov edx,OFFSET message
call WriteString
push eax
call STRREV
mov edx, OFFSET response
call WriteString
exit
main ENDP
END main
函数中的主要问题是更改AL和AH寄存器,然后使用EAX作为指针。
我决定根据您的代码编写一个新函数,仔细阅读并使用正确的模拟器调试代码
STRREV proc
;opening the function
push ebp
mov ebp, esp
push OFFSET response
call STRLEN
mov edx, [ebp+8] ;edx = offset string to reverse
mov esi, 0
dec eax
mov ebx,edx ;ebx stores the pointer to the first character
add ebx,eax` ;now ebx store the pointer to the last character before the '$'
reverseloop:
mov ah, [edx] ;ah stores the value at string[loop count]
mov al, [ebx] ;al stores the value at string[len-loop count-1]
;"swap ah,al" is logiclly unnecessary
;better solution:
mov [ebx],ah ; string[loop count] = string[len-loop count-1]
mov [edx],al ; string[len-loop count-1] = string[loop count]
inc edx ;increment of the right-most pointer
dec ebx ;decrement of the right-most pointer
cmp ebx, eax ;compares the left-most pointer to the right-most
jb reverseloop
jmp finish ;"ja", there is no need to check a condition twice
finish:
pop ebp
ret 4
STRREV endp
你为什么要在STRLEN中
mov edx,[ebp+16]
?第一个参数是+8,他错误地在mov ebp,esp
之后为2xpush添加了另一个+8,esp
,没有意识到push
只影响esp
,而不是ebp
(这两个push指令的值位于[esp+0]
===[ebp-8]
和[esp+4]
=[ebp-4]
…所以他在做[ebp+16]
而不是[esp+16]
或[ebp+8]
…不管怎样,他甚至懒得调试它,或者他忽略了strlen
代码在那一点上加载了错误的字符串地址这一事实。另外,我已经看到了这个源代码,我想知道他们是如何每次都产生相同的错误的,很有趣。但是在代码中有更多的错误。继续调试(一段时间后,您可能会注意到,寄存器eax
和al
共享一些位,以及ah
共享一些位,等等)为了更好的性能,不使用同一寄存器的单独部分,这会导致对某些CPU的错误依赖。例如,使用movzx eax,byte[edx]
和movzx ecx,byte[ebx]
以避免写入部分寄存器。(并且仍然存储为mov[ebx],al
/mov[edx],cl
和字节存储)。