0
StrReverse proc 

                   uses ecx eax edi esi,
                   StrAdd1:dword,   ;string 1 address
                   StrAdd2:dword    ;string 2 address



    std                     ;backward direction - set direction flag
    push StrAdd2            ;address of str2 arg to StrlenAsm
    call StrLenAsm          ;get length of str2
                            ;called function responsible for stack cleanup
    mov ecx,eax             ;length of string in ecx for rep
    mov edi,StrAdd1         ;edi gets destination address for copy
    mov esi,StrAdd2         ;esi gets source address for copy

loopTop:

    lodsb                   ;
    stosb                   ;
    loop loopTop

    mov byte ptr[edi],0     ;null terminate copied string
    ret                     ;return control to caller

StrReverse endp

I know STD is causing trouble, but I thought if I want reversing string, I should use std...could anyone explain to me why is that wrong and giving hints how to fix it?

Thank you for any further helps!

EDIT: So like this?

StrReverse proc 
               uses ecx eax edi esi, ;
               StrAdd1:dword,   ;string 1 address
               StrAdd2:dword    ;string 2 address


push StrAdd1            ;address of str2 arg to StrlenAsm
call StrLenAsm          ;get length of str2
                        ;called function responsible for stack cleanup
mov ecx,eax             ;length of string in ecx for rep
mov edi,StrAdd1         ;edi gets destination address for copy
mov esi,StrAdd2         ;esi gets source address for copy
add edi, ecx

loopTop:

cld                     ;forword direction - clear direction flag
lodsb                   ;read from source string
std                     ;backward direction - set direction flag
stosb                   ;write into distination string
loop loopTop

mov byte ptr[edi],0     ;null terminate copied string
ret                     ;return control to caller

StrReverse endp

It is still crashing =[

Z Feng
  • 13
  • 1
  • 4
  • Looks like x86 assembly - if I've got that wrong, please re-tag. And please bear in mind that there's more than one processor architecture in the world and more than one assembly language - so an architecture tag is important. – Damien_The_Unbeliever May 13 '14 at 07:22
  • Setting the direction flag means that the address (`esi`/`edi`) will be decremented after each string operation (`lodsb`/`stosb`). To reverse the source string you'll want to move forward through one string and backwards through the other - not backwards through both. Also keep in mind that when you move backwards through a string you should set the initial address to point at the last character of the string. – Michael May 13 '14 at 07:35
  • sorry about that. yes, you are right, it's assembly language for x86 processor. – Z Feng May 13 '14 at 07:40
  • @Michael I changed a bit, but still crushing =[ – Z Feng May 13 '14 at 07:50
  • You need to pay very close attention to where in memory you're reading and writing. Where does `string2 + strlen(string2)` point? (hint: it's not at the last character of the string). To where are you writing the NUL-terminator after the loop? (hint: it's not to the byte following the last character of the string). – Michael May 13 '14 at 07:58
  • @Michael But `string2` should between `esi` and `esi + strLen(string2)`, shouldn't it? – Z Feng May 13 '14 at 08:08

1 Answers1

0

I suggest to turn the directions because:

  1. When the loop ends - but at the latest at the end of the procedure - the direction flag must be set to "forward",

  2. mov byte ptr[edi],0: EDI must point behind the last character.

The length of the string is the right number for loop (which breaks at ECX==0) but not for ESI (which begins at offset 0). Search on Google for "off by one error".

This one works:

include \masm32\include\masm32rt.inc        ; MASM32 headers for 'printf'

.data
    str2 db "Hallo World!", 0
    str1 db SIZEOF str2 dup ('-')

.code
StrReverse proc uses ecx eax edi esi,
    StrAdd1:dword,              ;destination string address
    StrAdd2:dword               ;source string address

    mov ecx, SIZEOF str2 - 1    ; length of string (w/o last null) in ecx for rep
    mov edi,StrAdd1             ; edi gets destination address for copy
    mov esi,StrAdd2             ; esi gets source address for copy
    add esi, ecx                ; source pointer to the end
    sub esi, 1                  ; adjust esi to base 0 (1 char = +0 bytes)

    loopTop:

    std                         ; backward
    lodsb                       ; read from source string
    cld                         ; forward
    stosb                       ; write into distination string
    loop loopTop

    mov byte ptr[edi],0         ; null terminate copied string
    ret                         ; return control to caller

StrReverse endp

main PROC
    printf ("%s\n", OFFSET str2)

    push OFFSET str2
    push OFFSET str1
    call StrReverse

    printf ("%s\n", OFFSET str1)

    invoke ExitProcess, 0

main ENDP

END main
rkhb
  • 14,159
  • 7
  • 32
  • 60
  • Thank you very much! I realized before if I switch direction it will compile, but it was giving wrong result. I think i had off by one error, and also I was getting a wrong string length. Thank you so much for the answer, it works now. – Z Feng May 14 '14 at 01:01