home *** CD-ROM | disk | FTP | other *** search
-
- ; *******************************************************
- ; * *
- ; * Turbo Pascal Runtime Library Version 7.0 *
- ; * String Insertion *
- ; * *
- ; * Copyright (C) 1990-1993 Norbert Juffa *
- ; * *
- ; *******************************************************
-
- TITLE STINS
-
-
- CODE SEGMENT BYTE PUBLIC
-
- ASSUME CS:CODE
-
- ; Publics
-
- PUBLIC SInsert
-
- ;-------------------------------------------------------------------------------
- ; Insert standard proc.: Insert (VAR Obj, Target: STRING; MaxLen, Pos: INTEGER);
- ;
- ; Insert inserts string Obj in string Target at index Pos. The length of the
- ; resulting string Target may not exceed MaxLen. If the insertion point is at
- ; the end of Target, the routine appends Obj to Target. It does this by copying
- ; characters from Obj to the end of Target until all characters are copied or
- ; the maximum length MaxLen of Target has been reached. If Obj is to be inserted
- ; at the start or in the middle of Target, as indicated by Pos, the routine
- ; first creates a 'gap' in Target and then fills this gap with characters from
- ; Obj.
- ;
- ; On entry: [SP+4] Position
- ; [SP+6] Maximum length of target string
- ; [SP+8] Address of target string
- ; [SP+12] Address of object string
- ;-------------------------------------------------------------------------------
-
- SInsert PROC FAR
- PUSH BP ; save TURBO-Pascal framepointer
- PUSH DS ; save TURBO-Pascal data segment
- MOV BP, SP ; make new framepointer
- LDS SI, [BP+16] ; address of object string
- XOR CX, CX ; clear msb of length of object string
- OR CL, [SI] ; get length of object string
- JZ $end_ins ; exit, if length of object string zero
- MOV DX, [BP+8] ; DX=pos
- MOV AX, [BP+10] ; AX=maximum length of target string
- LES DI, [BP+12] ; address of target string
- MOV BL, ES:[DI] ; get current length of target string
- MOV BH, CH ; clear msb of length of target string
- DEC DX ; pos - 1
- CMP DH, 80h ; is pos-1 < 0 ?
- SBB BP, BP ; BP = FFFF if pos-1 > 0, else BP = 0
- AND DX, BP ; if pos-1 < 0 then set pos-1 = 0 (pos=1)
- SUB DX, BX ; pos-1 - targetlength
- SBB BP, BP ; BP = FFFF, if result negative, else 0
- AND DX, BP ; pos-1 - targetlength (0, if res. pos)
- ADD DX, BX ; pos-1, if result neg., else target len.
- MOV BP, AX ; maximum length of target string
- SUB BP, DX ; (maximum length - pos + 1) <= 0 ?
- JBE $end_ins ; yes, don't insert
- SUB BP, CX ; maximum length - pos + 1 - objectlength
- CLD ; select auto-increment
- JA $make_gap ; jump, if result positiv
- STOSB ; new targetlength will be maximum length
- ADD CX, BP ; adjust length of object string
- ADD DI, DX ; object string inserted after this char
- JMP $fill ; insert object
- $make_gap: MOV DX, CX ; save length of object string
- ADD CX, BX ; new targetlength = objectlen+targetlen
- SUB CX, AX ; new targetlength - maximum length
- SBB BX, BX ; BX=FFFF, if result negative, else BX=0
- AND CX, BX ; new targetlength - maximum length
- ADD AX, CX ; new targetlength = Min(TargLen, MaxLen)
- STOSB ; store it
- DEC DI ; correct pointer
- ADD CX, BP ; new targetlength - objectlength - pos+1
- ADD DI, AX ; this will be the last char in target
- XCHG AX, SI ; save offset of adress of object string
- MOV SI, DI ; now calculate
- SUB SI, DX ; the starting position
- PUSH DS ; save segment of address of objectstring
- MOV BX, ES ; let both segment register point
- MOV DS, BX ; to the segment containing targetstring
- STD ; auto-decrement
- REP MOVSB ; create gap
- MOV DI, SI ; object will be inserted after this char
- MOV CX, DX ; get length of object string
- MOV SI, AX ; get offset of address of object string
- POP DS ; get segment of address of object string
- INC DI ; object string will be inserted here
- CLD ; auto-increment
- $fill: INC SI ; first char of object string
- SHR CX, 1 ; number of chars to move odd ?
- JNC $even_ins ; no
- MOVSB ; yes, move a single byte
- $even_ins: REP MOVSW ; move the rest
- $end_ins: POP DS ; restore TURBO-Pascal data segment
- POP BP ; restore TURBO-Pascal frame pointer
- RET 12 ; return and pop parameters
- SInsert ENDP
-
- ALIGN 4
-
- CODE ENDS
-
- END