xref: /reactos/sdk/lib/ucrt/string/i386/strrev.asm (revision e3e520d1)
1        page    ,132
2        title   strrev - reverse a string in place
3;***
4;strrev.asm - reverse a string in place
5;
6;       Copyright (c) Microsoft Corporation. All rights reserved.
7;
8;Purpose:
9;       defines _strrev() - reverse a string in place (not including
10;       '\0' character)
11;
12;*******************************************************************************
13
14        .xlist
15        include cruntime.inc
16        .list
17
18page
19;***
20;char *_strrev(string) - reverse a string in place
21;
22;Purpose:
23;       Reverses the order of characters in the string.  The terminating
24;       null character remains in place.
25;
26;       Algorithm:
27;       char *
28;       _strrev (string)
29;             char *string;
30;             {
31;             char *start = string;
32;             char *left = string;
33;             char ch;
34;
35;             while (*string++)
36;                     ;
37;             string -= 2;
38;             while (left < string)
39;                     {
40;                     ch = *left;
41;                     *left++ = *string;
42;                     *string-- = ch;
43;                     }
44;             return(start);
45;             }
46;
47;       NOTE: There is a check for an empty string in the following code.
48;       Normally, this would fall out of the "cmp si,di" instruction in the
49;       loop portion of the routine.  However, if the offset of the empty
50;       string is 0 (as it could be in large model), then the cmp does not
51;       catch the empty string and the routine essentially hangs (i.e., loops
52;       moving bytes one at a time FFFFh times).  An explicit empty string
53;       check corrects this.
54;
55;Entry:
56;       char *string - string to reverse
57;
58;Exit:
59;       returns string - now with reversed characters
60;
61;Uses:
62;
63;Exceptions:
64;
65;*******************************************************************************
66
67        CODESEG
68
69        public  _strrev
70_strrev proc \
71        uses edi esi, \
72        string:ptr byte
73
74        mov     edi,[string]    ; di = string
75        mov     edx,edi         ; dx=pointer to string; save return value
76
77        mov     esi,edi         ; si=pointer to string
78        xor     eax,eax         ; search value (null)
79        or      ecx,-1          ; cx = -1
80repne   scasb                   ; find null
81        cmp     ecx,-2          ; is string empty? (if offset value is 0, the
82        je      short done      ; cmp below will not catch it and we'll hang).
83
84        sub     edi,2           ; string is not empty, move di pointer back
85                                ; di points to last non-null byte
86
87lupe:
88        cmp     esi,edi         ; see if pointers have crossed yet
89        jae     short done      ; exit when pointers meet (or cross)
90
91        mov     ah,[esi]        ; get front byte...
92        mov     al,[edi]        ;   and end byte
93        mov     [esi],al        ; put end byte in front...
94        mov     [edi],ah        ;   and front byte at end
95        add     esi,1           ; front moves up...
96        sub     edi,1           ;   and end moves down
97        jmp     short lupe      ; keep switching bytes
98
99done:
100        mov     eax,edx         ; return value: string addr
101
102        ret                     ; _cdecl return
103
104_strrev endp
105        end
106