home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BPL70N12.ZIP / STRSOURC.ZIP / STINS.ASM < prev    next >
Encoding:
Assembly Source File  |  1993-03-07  |  6.0 KB  |  110 lines

  1.  
  2. ; *******************************************************
  3. ; *                                                     *
  4. ; *     Turbo Pascal Runtime Library Version 7.0        *
  5. ; *     String Insertion                                *
  6. ; *                                                     *
  7. ; *     Copyright (C) 1990-1993 Norbert Juffa           *
  8. ; *                                                     *
  9. ; *******************************************************
  10.  
  11.              TITLE   STINS
  12.  
  13.  
  14. CODE         SEGMENT BYTE PUBLIC
  15.  
  16.              ASSUME  CS:CODE
  17.  
  18. ; Publics
  19.  
  20.              PUBLIC  SInsert
  21.  
  22. ;-------------------------------------------------------------------------------
  23. ; Insert standard proc.: Insert (VAR Obj, Target: STRING; MaxLen, Pos: INTEGER);
  24. ;
  25. ; Insert inserts string Obj in string Target at index Pos. The length of the
  26. ; resulting string Target may not exceed MaxLen. If the insertion point is at
  27. ; the end of Target, the routine appends Obj to Target. It does this by copying
  28. ; characters from Obj to the end of Target until all characters are copied or
  29. ; the maximum length MaxLen of Target has been reached. If Obj is to be inserted
  30. ; at the start or in the middle of Target, as indicated by Pos, the routine
  31. ; first creates a 'gap' in Target and then fills this gap with characters from
  32. ; Obj.
  33. ;
  34. ; On entry:  [SP+4]  Position
  35. ;            [SP+6]  Maximum length of target string
  36. ;            [SP+8]  Address of target string
  37. ;            [SP+12] Address of object string
  38. ;-------------------------------------------------------------------------------
  39.  
  40. SInsert      PROC    FAR
  41.              PUSH    BP                ; save TURBO-Pascal framepointer
  42.              PUSH    DS                ; save TURBO-Pascal data segment
  43.              MOV     BP, SP            ; make new framepointer
  44.              LDS     SI, [BP+16]       ; address of object string
  45.              XOR     CX, CX            ; clear msb of length of object string
  46.              OR      CL, [SI]          ; get length of object string
  47.              JZ      $end_ins          ; exit, if length of object string zero
  48.              MOV     DX, [BP+8]        ; DX=pos
  49.              MOV     AX, [BP+10]       ; AX=maximum length of target string
  50.              LES     DI, [BP+12]       ; address of target string
  51.              MOV     BL, ES:[DI]       ; get current length of target string
  52.              MOV     BH, CH            ; clear msb of length of target string
  53.              DEC     DX                ; pos - 1
  54.              CMP     DH, 80h           ; is pos-1 < 0 ?
  55.              SBB     BP, BP            ; BP = FFFF if pos-1 > 0, else BP = 0
  56.              AND     DX, BP            ; if pos-1 < 0 then set pos-1 = 0 (pos=1)
  57.              SUB     DX, BX            ; pos-1 - targetlength
  58.              SBB     BP, BP            ; BP = FFFF, if result negative, else 0
  59.              AND     DX, BP            ; pos-1 - targetlength (0, if res. pos)
  60.              ADD     DX, BX            ; pos-1, if result neg., else target len.
  61.              MOV     BP, AX            ; maximum length of target string
  62.              SUB     BP, DX            ; (maximum length - pos + 1) <= 0 ?
  63.              JBE     $end_ins          ; yes, don't insert
  64.              SUB     BP, CX            ; maximum length - pos + 1 - objectlength
  65.              CLD                       ; select auto-increment
  66.              JA      $make_gap         ; jump, if result positiv
  67.              STOSB                     ; new targetlength will be maximum length
  68.              ADD     CX, BP            ; adjust length of object string
  69.              ADD     DI, DX            ; object string inserted after this char
  70.              JMP     $fill             ; insert object
  71. $make_gap:   MOV     DX, CX            ; save length of object string
  72.              ADD     CX, BX            ; new targetlength = objectlen+targetlen
  73.              SUB     CX, AX            ; new targetlength - maximum length
  74.              SBB     BX, BX            ; BX=FFFF, if result negative, else BX=0
  75.              AND     CX, BX            ; new targetlength - maximum length
  76.              ADD     AX, CX            ; new targetlength = Min(TargLen, MaxLen)
  77.              STOSB                     ; store it
  78.              DEC     DI                ; correct pointer
  79.              ADD     CX, BP            ; new targetlength - objectlength - pos+1
  80.              ADD     DI, AX            ; this will be the last char in target
  81.              XCHG    AX, SI            ; save offset of adress of object string
  82.              MOV     SI, DI            ; now calculate
  83.              SUB     SI, DX            ;  the starting position
  84.              PUSH    DS                ; save segment of address of objectstring
  85.              MOV     BX, ES            ; let both segment register point
  86.              MOV     DS, BX            ; to the segment containing targetstring
  87.              STD                       ; auto-decrement
  88.              REP     MOVSB             ; create gap
  89.              MOV     DI, SI            ; object will be inserted after this char
  90.              MOV     CX, DX            ; get length of object string
  91.              MOV     SI, AX            ; get offset of address of object string
  92.              POP     DS                ; get segment of address of object string
  93.              INC     DI                ; object string will be inserted here
  94.              CLD                       ; auto-increment
  95. $fill:       INC     SI                ; first char of object string
  96.              SHR     CX, 1             ; number of chars to move odd ?
  97.              JNC     $even_ins         ; no
  98.              MOVSB                     ; yes, move a single byte
  99. $even_ins:   REP     MOVSW             ; move the rest
  100. $end_ins:    POP     DS                ; restore TURBO-Pascal data segment
  101.              POP     BP                ; restore TURBO-Pascal frame pointer
  102.              RET     12                ; return and pop parameters
  103. SInsert      ENDP
  104.  
  105.              ALIGN   4
  106.  
  107. CODE         ENDS
  108.  
  109.              END
  110.