String 汇编语言x86中的字符串反转

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

我是汇编语言的新手,我有一段代码,假设它可以反转字符串的长度,现在我知道我已经接近了,但不管是什么原因,程序总是在我身上崩溃。问题出在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 

    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
之后为2x
push添加了另一个+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
和字节存储)。