Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : STRREV.ASM

 
Output of file : STRREV.ASM contained in archive : VCCRT2.ZIP
page ,132
title strrev - reverse a string in place
;***
;strrev.asm - reverse a string in place
;
; Copyright (c) 1985-1992, Microsoft Corporation. All rights reserved.
;
;Purpose:
; defines strrev() - reverse a string in place (not including
; '\0' character)
;
;*******************************************************************************

.xlist
include version.inc
include cmacros.inc
include defsegs.inc
.list

; code for model-independent version for llibccrt goes into _RTEXT segment

ifdef _LOAD_DGROUP
ifdef MODELINDEP
CrtDefSegs
CODE_SEG equ
CS_ASSUME equ <_RTEXT> ; assumes macro won't handle rcode
else
CODE_SEG equ
CS_ASSUME equ
endif
else
CODE_SEG equ
CS_ASSUME equ
endif

% sBegin CODE_SEG

% assumes cs,CS_ASSUME
assumes ds,data

page
;***
;char *_strrev(string) - reverse a string in place
;
;Purpose:
; Reverses the order of characters in the string. The terminating
; null character remains in place.
;
; Algorithm:
; char *
; _strrev (string)
; char *string;
; {
; char *start = string;
; char *left = string;
; char ch;
;
; while (*string++)
; ;
; string -= 2;
; while (left < string)
; {
; ch = *left;
; *left++ = *string;
; *string-- = ch;
; }
; return(start);
; }
;
; NOTE: There is a check for an empty string in the following code.
; Normally, this would fall out of the "cmp si,di" instruction in the
; loop portion of the routine. However, if the offset of the empty
; string is 0 (as it could be in large model), then the cmp does not
; catch the empty string and the routine essentially hangs (i.e., loops
; moving bytes one at a time FFFFh times). An explicit empty string
; check corrects this.
;
;Entry:
; char *string - string to reverse
;
;Exit:
; returns string - now with reversed characters
;
;Uses:
;
;Exceptions:
;
;*******************************************************************************

ifdef MODELINDEP

cProc _fstrrev,,<>

else

cProc _strrev,,<>

endif

parmdp string

cBegin
push di
push si

if sizeD
push ds ; save ds
les di,string ; di=pointer to string (es=segment part)
push es ; ds points there too
pop ds
else
push ds ; fix es for small/middle model
pop es
mov di,string ; di=pointer to string
endif

mov bx,di ; bx=pointer to string; save return value
mov si,di ; si=pointer to string
xor ax,ax ; search value (null)
mov cx,-1
repne scasb ; find null

if sizeD
je @F ; terminal null found, nothing special needed
;
; the string must be of maximum length and di must point to terminal null
; character (rather than one past it).
;
dec di ; di points to last non-null byte
jmp short lupe
@@:
endif

cmp cx,-2 ; is string empty? (if offset value is 0, the
je done ; cmp below will not catch it and we'll hang).

dec di ; string is not empty, move di pointer back
dec di ; di points to last non-null byte

lupe:
cmp si,di ; see if pointers have crossed yet
jae done ; exit when pointers meet (or cross)

mov ah,[si] ; get front byte...
mov al,[di] ; and end byte
mov [si],al ; put end byte in front...
mov [di],ah ; and front byte at end
inc si ; front moves up...
dec di ; and end moves down
jmp short lupe ; keep switching bytes

done:
mov ax,bx ; return value: string addr

if sizeD
mov dx,ds ; segment part of addr
pop ds ; restore ds
endif

pop si
pop di
cEnd

% sEnd CODE_SEG
end


  3 Responses to “Category : C++ Source Code
Archive   : VCCRT2.ZIP
Filename : STRREV.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/