home *** CD-ROM | disk | FTP | other *** search
- ; _______________________________________________________________
- ; | |
- ; | Copyright (C) 1989,1990 Steven Lutrov |
- ; |_______________________________________________________________|____
- ; | | |
- ; | Program Title : FastStr.Asm | | ___
- ; | Author : Steven Lutrov | | |
- ; | Revision : 2.01 | | |
- ; | Date : 1990-03-16 | | |
- ; | Language : Turbo Assembler | | |
- ; | | | |
- ; | Description : Assembly Functions For String Manipulation. | | |
- ; | : Tested on Turbo Pascal 5.0 & 5.5 | | |
- ; | | | |
- ; |_______________________________________________________________| | |
- ; | | |
- ; |________________________________________________________________| |
- ; | |
- ; |_________________________________________________________________|
- ;
-
-
- Code Segment Word Public
-
- Assume Cs:Code,Ds:Data
-
- Public Changechar,Compare,Stringend,Deletechar,Deleteleft,Deleteright
- Public Leftend,Lowercase,Overwrite,Padcentre,Padends,Padleft,Padright
- Public Replace,Rightend,Seekstring,Stringof,Uppercase,Wordcount
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Changechar(Var Strx: Stype; Search,Replace: Char);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Changechar Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,0 ;Assume Char Found
- Les Di,Dword Ptr[Bp+10] ;Es:Di Pts To Strx
- Sub Dx,Dx ;Flags That A Char Found
- Mov Al,[Bp+6] ;Get Replacement Char
- Mov Ah,[Bp+8] ;Search Character
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get String Length
- Jcxz Changechar3 ;Quit If Null String
- Changechar1: Inc Di ;Forward String Ptr
- Cmp Es:[Di],Ah ;Search Char?
- Jne Changechar2 ;Jump Ahead If Not
- Mov Es:[Di],Al ;Else Change Char
- Inc Dx ;Flag That A Char Found
- Changechar2: Loop Changechar1 ;Go Do Next Char
- Or Dx,Dx ;Test If Char Found
- Jnz Changechar4 ;Jump Ahead If So
- Changechar3: Inc Errreturn ;Else 1 = Char Not Found
- Changechar4: Pop Bp ;Restore Bp And Quit
- Ret 8
- Changechar Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Compare(Strg1,Strg2: Stype): Boolean;
- ;
- ;
- Compare Proc Far
- Mov Bx,Sp ;Bx Pts To Stack
- Push Ds ;Save Turbo'S Ds
- Les Di,Ss:Dword Ptr[Bx+8] ;Es:Di Pts To Strg1
- Lds Si,Ss:Dword Ptr[Bx+4] ;Ds:Si Pts To Strg2
- Sub Cx,Cx ;Clear Cx
- Mov Cl,[Si] ;Get Strg2 Length
- Cmp Cl,Es:[Di] ;Equal To Strg1 Length?
- Jne Compare6 ;Quit If Not
- Jcxz Compare5 ;Quit If Both Null
- Compare1: Inc Di ;Forward Strg1 Ptr
- Inc Si ;Forward Strg2 Ptr
- Mov Al,[Si] ;Get Strg2 Char
- Cmp Al,Es:[Di] ;Compare To Strg1 Char
- Je Compare4 ;Loop If Equal
- Cmp Al,122 ;Above Lower Case Vals?
- Ja Compare6 ;Quit If So
- Cmp Al,97 ;Lower Case Char?
- Jnae Compare2 ;Jump Ahead If Not
- Sub Al,32 ;Make Lower Case
- Jmp Short Compare3 ;Go Test It
- Compare2: Cmp Al,90 ;Above Upper Case Vals?
- Ja Compare6 ;Quit If So
- Cmp Al,65 ;Upper Case Char?
- Jnae Compare6 ;Quit If Not
- Add Al,32 ;Make Lower Case
- Compare3: Cmp Al,Es:[Di] ;Compare To Strg1 Char
- Jne Compare6 ;Quit If Not Equal
- Compare4: Loop Compare1 ;Go Do Next Char
- Compare5: Mov Al,1 ;Return True
- Jmp Short Compare7 ;Jump Ahead
- Compare6: Mov Al,0 ;Return False
- Compare7: Pop Ds ;Restore Ds And Quit
- Ret 8
- Compare Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Stringend(Strx: Stype; Numberchars: Integer): Stype;
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Stringend Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Save Ds
- Les Di,Dword Ptr[Bp+12] ;Es:Di Pts To Return Strx
- Lds Si,Dword Ptr[Bp+8] ;Ds:Si Pts To Source Strx
- Sub Cx,Cx ;Clear Cx
- Mov Es:[Di],Cl ;Return Null String If Error
- Mov Cl,[Bp+6] ;Get Numberchars (255 Max)
- Sub Bx,Bx ;Clear Bx
- Mov Bl,[Si] ;Strx Length In Bx
- Mov Dl,1 ;1 = Null String
- Or Bl,Bl ;Test For Null String
- Jz Stringend3 ;Quit Routine If Null
- Dec Dl ;0 = No Error
- Cmp Cx,Bx ;Numberchars < Length?
- Jbe Stringend1 ;Jump Ahead If So
- Mov Cx,Bx ;Else Return Whole String
- Mov Dl,2 ;2 = Numberchars Greater Than Length
- Stringend1: Mov Es:[Di],Cl ;Return Strx Descriptor
- Sub Bx,Cx ;Length Minus Numberchars
- Inc Di ;Forward Return Strx Ptr To First Char
- Inc Si ;Save For Source Strx
- Add Si,Bx ;Add Starting Offset To Source
- Stringend2: Cld ;Direction Forward
- Rep Movsb ;Move The Portion Of The String
- Stringend3: Pop Ds ;Restore Ds
- Mov Errreturn,Dl ;Set Errreturn
- Pop Bp ;Restore Bp And Quit
- Ret 6
- Stringend Endp
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Deletechar(Var Strx: Stype; Ch: Char);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- ;
- Deletechar Proc Far
- Cld ;Set Direction Flag
- Mov Errreturn,1 ;1 = Char Not Found
- Push Bp ;Save Bp
- Push Ds ;Save Ds
- Mov Bp,Sp ;Set Up Stack Frame
- Les Di,Dword Ptr [Bp+10] ;Get String Address
- Mov Al,[Bp+8] ;Get Char To Delete
- Sub Bp,Bp ;Use Bp As Errreturn Flag
- Push Es ;Push Es...
- Pop Ds ;...Then Copy Into Ds
- Mov Bx,Di ;Bx Will Pt To Descriptor
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get String Length
- Jcxz Deletechar3 ;Quit If Null String
- Inc Di ;Pt Di To Start Of String
- Mov Si,Di ;Copy Into Si
- Cld ;Direction Forward In Movsb
- Deletechar1: Cmp [Si],Al ;Check For The Character
- Je Deletechar2 ;Jump If Char Found
- Movsb ;Move The Char
- Loop Deletechar1 ;Go Check Next Char
- Jmp Short Deletechar3 ;Finished
- Deletechar2: Inc Si ;Forward Source Ptr
- Dec Byte Ptr[Bx] ;Decrease String Descriptor
- Inc Bp ;Flag That Char Found
- Loop Deletechar1 ;Go Check Next Char
- Deletechar3: Pop Ds ;Restore Ds
- Or Bp,Bp ;Test Bp For Zero
- Jz Deletechar4 ;Jump If No Match Found
- Dec Errreturn ;Else Errreturn = 0
- Deletechar4: Pop Bp ;Restore Bp And Quit
- Ret 6
- Deletechar Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Deleteleft(Var Strx: Stype; Border: Char);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Deleteleft Proc Far
- Mov Errreturn,0 ;Assume No Error
- Push Ds ;Ds Is Changed
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Les Di,Dword Ptr [Bp+10] ;Es:Di Pts To String
- Lds Si,Dword Ptr [Bp+10] ;So Does Ds:Si
- Mov Si,Di ;Keep Si At Descriptor
- Mov Al,[Bp+8] ;Get The Border Character
- Pop Bp ;Restore Bp
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;String Length In Cx
- Jcxz Deleteleft1 ;Quit If Null
- Mov Bx,Cx ;Copy Of String Length In Bx
- Inc Di ;Pt To First Byte Of String
- Cld ;Direction Forward
- Repne Scasb ;Look For The Border Character
- Jnz Deleteleft1 ;Quit If Can'T Find Char
- Mov Dx,Di ;Copy Of Di To Dx
- Dec Dx ;Point To Char Before
- Sub Dx,Si ;Number Characters To Delete
- Dec Dx ;Don'T Delete Border Char
- Mov Cx,Bx ;Old String Length
- Sub Cx,Dx ;New String Length
- Mov [Si],Cl ;Set New String Length
- Inc Si ;Point Si To Start Of String
- Xchg Di,Si ;Reverse Pointers For Movsb
- Dec Si ;Don'T Remove Border Char
- Rep Movsb ;Move The Characters
- Pop Ds ;Restore Ds
- Ret 6 ;Quit
- Deleteleft1: Pop Ds ;---Error Case:
- Inc Errreturn ;1 = Null String Or Char Not Found
- Ret 6 ;Quit
- Deleteleft Endp
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Deleteright(Var Strx: Stype; Border: Char);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Deleteright Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Les Di,Dword Ptr [Bp+8] ;Load String Address
- Mov Si,Di ;Keep Si At Descriptor
- Mov Al,[Bp+6] ;Get The Border Character
- Sub Cx,Cx ;Clear Cx
- Mov Errreturn,1 ;1 = Null String
- Mov Cl,Es:[Di] ;String Length In Cx
- Jcxz Deleteright3 ;Quit If Null
- Add Di,Cx ;Point Di To End Of String
- Deleteright1: Cmp [Di],Al ;Test For The Border Char
- Je Deleteright2 ;If Found, Jump Ahead
- Dec Di ;Else, Point To Next Char
- Loop Deleteright1 ;Go Test Next Char
- Jmp Short Deleteright3 ;Char Not Found
- Deleteright2: Mov Es:[Si],Cl ;Set New String Length
- Dec Errreturn ;No Error
- Deleteright3: Pop Bp ;Restore Bp And Quit
- Ret 6
- Deleteright Endp
-
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Leftend(Var Strx: Stype; Border: Char): Stype;
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Leftend Proc Far
- Mov Dl,1 ;1 = Border Char Not Found
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Save Ds
- Les Di,Dword Ptr[Bp+8] ;Es:Di Pts To Strx
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;String Length To Cx
- Jcxz Leftend2 ;Quit If Zero
- Inc Di ;Pt To 1St Byte Of Strx
- Mov Bx,Di ;Copy Start Position
- Cld ;Direction Forward
- Mov Al,[Bp+6] ;Border Character
- Repne Scasb ;Search For The Character
- Jnz Leftend1 ;Not Found, Skip Ptr Dec
- Dec Di ;Pull Back Ptr
- Dec Dl ;Errreturn = 0, No Error
- Leftend1: Sub Di,Bx ;Distance To Char
- Mov Cx,Di ;Use As Counter
- Mov Ax,Es ;Transfer Es...
- Mov Ds,Ax ;To Ds
- Mov Si,Bx ;Now Ds:Si Pts To Start Of Strx
- Leftend2: Les Di,Dword Ptr[Bp+12] ;Now Es:Di Pts To Return String
- Mov Es:[Di],Cl ;Set Return Descriptor
- Jcxz Leftend3 ;Jump Ahead If Null Strx
- Inc Di ;Forward Ptr
- Rep Movsb ;Move The String
- Leftend3: Pop Ds ;Restore Ds
- Mov Errreturn,Dl ;Set Errreturn
- Pop Bp ;Restore Bp And Quit
- Ret 6
- Leftend Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Lowercase(Var Strx: Stype);
- ;
- ;
- Lowercase Proc Far
- Mov Bx,Sp ;Bx Points To Stack
- Les Di,Ss:Dword Ptr[Bx+4] ;Es:Di Pts To String
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get String Length
- Jcxz Lowercase3 ;Quit If Null
- Lowercase1: Inc Di ;Pt To Next Char Of Strx
- Cmp Es:Byte Ptr [Di],'Z' ;Test High Char
- Ja Lowercase2 ;Skip Ahead If Above
- Cmp Es:Byte Ptr [Di],'A' ;Test Low Char
- Jb Lowercase2 ;Skip Ahead If Below
- Add Es:Byte Ptr [Di],32 ;Change The Char
- Lowercase2: Loop Lowercase1 ;Go Test Next Character
- Lowercase3: Ret 4
- Lowercase Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Overwrite(Var Strx: Stype; Substrg: Stype; Position: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Overwrite Proc Far
- Mov Errreturn,0 ;Assume No Error
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Ds Is Changed
- Les Di,Dword Ptr [Bp+12] ;Es:Di Pts To Strx
- Mov Bx,Di ;Bx Points To Strx
- Sub Cx,Cx ;Clear Cx
- Mov Cl,[Bp+6] ;Position In Cx
- Jcxz Overwrite2 ;Quit If Zero
- Cmp Cl,Es:[Di] ;Is Position Within Strx?
- Ja Overwrite2 ;Quit If Not
- Mov Dx,Cx ;Keep For Error Check
- Add Di,Cx ;Add To String Ptr
- Lds Si,Dword Ptr [Bp+8] ;Ds:Si Pts To Substring
- Mov Cl,[Si] ;Get The String Descriptor
- Jcxz Overwrite2 ;Quit If Null
- Add Dx,Cx ;Dx = Substr Endchar + 1
- Sub Dl,Es:[Bx] ;Subtract String Length
- Cmp Dl,1 ;Will Substring Fit?
- Jg Overwrite3 ;If Not, Quit Routine
- Overwrite1: Inc Si ;Pt To Next Substrg Char
- Mov Dl,[Si] ;Get The Char
- Mov Es:[Di],Dl ;Insert Into The String
- Inc Di ;Pt To Next Char Of Strx
- Loop Overwrite1 ;Go Do Next Character
- Pop Ds ;Restore Ds
- Jmp Short Overwrite5 ;Terminate Without Error
- Overwrite2: Mov Al,1 ;1 = Position Not In String
- Jmp Short Overwrite4 ;Jump Ahead
- Overwrite3: Mov Al,2 ;2 = Substring Won'T Fit
- Overwrite4: Pop Ds ;Restore Ds
- Mov Errreturn,Al ;Set Errreturn
- Overwrite5: Pop Bp ;Restore Bp And Quit
- Ret 10
- Overwrite Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Padcentre(Var Strx: Stype; Ch: Char; Position,Length: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Padcentre Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,1 ;1 = Error
- Les Di,Dword Ptr[Bp+12] ;Es:Di Pts To Strx
- Mov Si,Di ;Copy In Si
- Sub Dx,Dx ;Clear Dx
- Mov Dl,[Bp+6] ;New Strx Length In Dx (255 Max)
- Or Dx,Dx ;Test For Zero Length
- Jz Padcentre6 ;Quit If Zero
- Mov Bx,Dx ;Copy Of Length In Bx
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get Current Strx Length
- Cmp Cx,Dx ;Compare To New Length
- Jae Padcentre6 ;Quit If Longer
- Mov Es:[Di],Dl ;Set New Strx Length
- Sub Dx,Cx ;Dx = Number Pad Chars
- Sub Ax,Ax ;Clear Ax
- Mov Al,[Bp+8] ;Get Position
- Or Ax,Ax ;Test For 0
- Jnz Padcentre1 ;Jump If Not 0
- Inc Ax ;Else Make 1
- Padcentre1: Cmp Ax,Cx ;Past End Of String?
- Jna Padcentre2 ;Jump Ahead If Not
- Add Di,Cx ;Offset To End Of Strx
- Jmp Short Padcentre4 ;Go Write Pad Chars
- Padcentre2: Add Si,Bx ;Add To Target
- Add Di,Bx ;Add To Source
- Sub Di,Dx ;Source Minus Number Pad Chars
- Sub Cx,Ax ;Subtract From Strx Len
- Inc Cx ;Ax Pts From 0, Adjust
- Padcentre3: Mov Al,Es:[Di] ;Get A Char
- Mov Es:[Si],Al ;Shift It Upwards
- Dec Di ;Pull Back Source Ptr
- Dec Si ;Target Ptr Too
- Loop Padcentre3 ;Do Next Char
- Padcentre4: Mov Cx,Dx ;Number Pad Characters
- Mov Al,[Bp+10] ;Get Pad Character
- Padcentre5: Inc Di ;Forward Ptr
- Mov Es:[Di],Al ;Write Pad Character
- Loop Padcentre5 ;Go Do The Next
- Dec Errreturn ;0 = No Error
- Padcentre6: Pop Bp ;Restore Bp And Quit
- Ret 10
- Padcentre Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Padends(Var Strx: Stype; Ch: Char; Length: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Padends Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,1 ;1 = Error
- Les Di,Dword Ptr[Bp+10] ;Es:Di Pts To Strx
- Mov Si,Di ;Copy In Si
- Sub Dx,Dx ;Clear Dx
- Mov Dl,[Bp+6] ;New Strx Length In Dx
- Or Dx,Dx ;Test For Zero Length
- Jz Padends7 ;Quit If Zero
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get Strx Length
- Cmp Cx,Dx ;Is Strx Gt New Length
- Jae Padends7 ;Quit If True
- Mov Es:[Di],Dl ;Set New Strx Length
- Push Di ;Copy Of Start Of String
- Sub Dx,Cx ;Dx = Number Pad Chars
- Mov Bx,Dx ;Copy To Bx
- Shr Bx,1 ;Chars Div 2
- Sub Dx,Bx ;Dx Is Same Or 1 Larger
- Add Di,Cx ;Pt To End Of Strx
- Add Si,Dx ;Offset For Upward Shift
- Add Si,Cx ;Plus String Length
- Or Cx,Cx ;Test For Null String
- Jnz Padends1 ;Jump Ahead If Not Null
- Sub Bx,Bx ;
- Mov Bl,[Bp+6] ;Otherwise Set At Right Padding
- Jmp Short Padends3 ;Jump To Rightside Padding
- Padends1: Push Si ;Save End Position
- Padends2: Mov Al,Es:[Di] ;Get A Char
- Mov Es:[Si],Al ;Shift It
- Dec Di ;Dec Source Ptr
- Dec Si ;Dec Target Ptr
- Loop Padends2 ;Go Do Next
- Pop Si ;Restore End Position
- Padends3: Mov Al,[Bp+8] ;Get The Pad Char
- Mov Cx,Bx ;Number To Pad On Right
- Jcxz Padends5 ;Jump Ahead If Zero
- Padends4: Inc Si ;Forward Ptr
- Mov Es:[Si],Al ;Write Pad Char On Right
- Loop Padends4 ;Go Do Next
- Padends5: Pop Di ;Di Pts To Bottom Of Strx
- Mov Cx,Dx ;Number Pad Chars On Left
- Or Cx,Cx ;Test For Zero
- Jz Padends7 ;Quit If Zero
- Padends6: Inc Di ;Forward Ptr
- Mov Es:[Di],Al ;Write Pad Char On Left
- Loop Padends6 ;Go Do Next
- Dec Errreturn ;0 = No Error
- Padends7: Pop Bp ;Restore Bp And Quit
- Ret 8
- Padends Endp
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Padleft(Var Strx: Stype; Ch: Char; Length: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Padleft Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,1 ;1 = Error
- Push Ds ;Save Ds
- Les Di,Dword Ptr[Bp+10] ;Get String Address
- Push Es ;Push Es...
- Pop Ds ;...Then Load Into Ds
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;String Length In Cl
- Mov Bx,[Bp+6] ;New String Length In Bl
- Dec Bx ;Dec Bx For Test
- Cmp Bx,254 ;In Range?
- Ja Padleft2 ;Quit If Not
- Inc Bx ;Readjust
- Cmp Cl,Bl ;Compare The Two Lengths
- Jae Padleft2 ;Quit If Old Len >= New
- Mov Es:[Di],Bl ;Set New String Length
- Mov Si,Di ;Pt Si To Descriptor
- Add Si,Cx ;Now Pt Si To String End
- Add Di,Bx ;Pt Di To New String End
- Sub Bx,Cx ;Number Of Spaces To Pad
- Std ;Set Direction Flag
- Rep Movsb ;Move Old String Right
- Mov Cx,Bx ;Spaces To Pad In Cx
- Mov Al,[Bp+8] ;Get Pad Character
- Padleft1: Mov [Di],Al ;Insert Pad Char
- Dec Di ;Move To Next Position
- Loop Padleft1 ;Go Do Next Char
- Pop Ds ;Restore Ds
- Dec Errreturn ;0 = No Error
- Jmp Short Padleft3 ;Jump Ahead And Quit
- Padleft2: Pop Ds ;Exit With Error
- Padleft3: Pop Bp ;Restore Bp And Quit
- Ret 8
- Padleft Endp
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Padright(Var Strx: Stype; Ch: Char; Length: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Padright Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,1 ;1 = Error
- Les Di,Dword Ptr[Bp+10] ;Get String Address
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;String Length In Cl
- Mov Bx,[Bp+6] ;New String Length
- Dec Bx ;Dec Bx For Test
- Cmp Bx,254 ;In Range?
- Ja Padright2 ;Quit If Not
- Inc Bx ;Readjust
- Cmp Cl,Bl ;Compare The Two Lengths
- Jae Padright2 ;Quit If Old Len>=New Len
- Mov Es:[Di],Bl ;Set New String Length
- Add Di,Cx ;Point Di To End Of Strx
- Sub Bx,Cx ;Sub Old Len From New Len
- Mov Cx,Bx ;Use As Counter
- Mov Al,[Bp+8] ;Get Pad Character
- Padright1: Inc Di ;Increment Pointer
- Mov Es:[Di],Al ;Insert A Pad Char
- Loop Padright1 ;Go Do Next Char
- Dec Errreturn ;0 = No Error
- Padright2: Pop Bp ;Restore Bp And Quit
- Ret 8
- Padright Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Replace(Var Strx: Stype; Substrg: Stype; Position,Chars: Integer);
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Replace Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Save Ds Too
- Mov Errreturn,1 ;1 = Error Has Occured
- Les Di,Dword Ptr[Bp+14] ;Es:Di Pts To Strx
- Sub Cx,Cx ;Clear Cx
- Mov Byte Ptr[Bp+7],Cl ;Use Byte As If Word
- Mov Cl,Es:[Di] ;Get Strx Length
- Or Cx,Cx ;Test For Null String
- Jnz Replace2 ;Jump Ahead If Not
- Replace1: Jmp Replace9 ;Else Quit Routine
- Replace2: Sub Bx,Bx ;Clear Bx
- Mov Bl,[Bp+8] ;Position To Bx
- Or Bx,Bx ;Position 0?
- Jz Replace1 ;Quit If Zero
- Cmp Bx,Cx ;Within Strx?
- Jnbe Replace1 ;Quit If Not
- Lds Si,Dword Ptr[Bp+10] ;Ds:Si Pts To Substrg
- Sub Dx,Dx ;Clear Dx
- Mov Dl,[Si] ;Substring Length
- Or Dx,Dx ;Test For Null
- Jz Replace1 ;Quit If Null
- Mov Ax,Cx ;Strx Length
- Sub Ax,Bx ;Minus Position
- Inc Ax ;Number Deletable Chars
- Cmp Ax,[Bp+6] ;Cmp To Num Chars To Del
- Jb Replace9 ;Quit If Not Enough Chars
- Mov Ax,[Bp+6] ;Chars To Delete
- Cmp Ax,Dx ;Num Chars Del/Replace
- Ja Replace3 ;Must Shift Chars Down
- Jb Replace5 ;Must Shift Chars Up
- Add Di,Bx ;No Shift, Di To Overlay
- Jmp Short Replace7 ;No Write Substring
- Replace3: Sub Ax,Dx ;Strx Shortened This Much
- Sub Cx,Ax ;New String Length
- Mov Es:[Di],Cl ;Set Descriptor
- Add Di,Bx ;Pt To Substrg Position
- Mov Si,Di ;Copy To Si
- Add Si,Dx ;Pt To End Of Substrg + 1
- Sub Cx,Bx ;Chars Following Substrg
- Inc Cx ;Adjust
- Mov Bx,Si ;End Of Substring Pos
- Add Bx,Ax ;Forward To Shift Point
- Replace4: Mov Al,Es:[Bx] ;Get A Char
- Mov Es:[Si],Al ;Move It Downward
- Inc Si ;Inc Target Ptr
- Inc Bx ;Inc Source Ptr
- Loop Replace4 ;Loop Till Finished
- Jmp Short Replace7 ;Go Write Substring
- Replace5: Neg Ax ;Dx Minus Ax In Ax
- Add Ax,Dx ;Ax = Increased Strx Len
- Add Cx,Ax ;New Length
- Mov Es:[Di],Cl ;Set Descriptor
- Mov Si,Di ;Si Pts To Start Of Strx
- Add Di,Bx ;Point Di To Substrg Pos
- Add Si,Cx ;Si Pts To End Of Strx
- Mov Bx,Si ;Copy To Bx
- Sub Bx,Ax ;Move To Shift Point
- Sub Cx,[Bp+8] ;Length Minus Position
- Dec Cx ;Adjust
- Jcxz Replace7 ;Boundary Case
- Replace6: Mov Al,Es:[Bx] ;Get A Character
- Mov Es:[Si],Al ;Move It Upwards
- Dec Si ;Dec Target Ptr
- Dec Bx ;Get Source Ptr
- Loop Replace6 ;Loop Till Finished
- Replace7: Lds Si,Dword Ptr[Bp+10] ;Point Ds:Si Back To Substrg
- Inc Si ;Forward Si To First Char
- Replace8: Mov Cl,[Si] ;Get Char From Substring
- Mov Es:[Di],Cl ;Move To Strx
- Inc Si ;Forward Source Ptr
- Inc Di ;Forward Target Ptr
- Dec Dx ;Dec Substring Ctr
- Jnz Replace8 ;Loop Till Finished
- Pop Ds ;Restore Ds
- Dec Errreturn ;0 = No Error
- Jmp Short Replace10 ;Jump Ahead
- Replace9: Pop Ds ;Terminate With Error
- Replace10: Pop Bp ;Restore Bp And Quit
- Ret 12
- Replace Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Rightend(Var Strx: Stype; Border: Char): Stype;
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Rightend Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Save Ds
- Mov Dl,1 ;1 = Border Char Not Found
- Les Di,Dword Ptr[Bp+8] ;Es:Di Pts To Strx
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;String Length To Cx
- Jcxz Rightend2 ;Quit If Zero
- Add Di,Cx ;Pt To Last Byte Of Strx
- Mov Si,Di ;Copy Start Position
- Std ;Direction Flag Backward
- Mov Al,[Bp+6] ;Border Character
- Repne Scasb ;Search For The Character
- Jnz Rightend1 ;Skip Inc If Not Found
- Inc Di ;Discard Border Char
- Dec Dl ;Errreturn = 0, No Error
- Rightend1: Inc Di ;Step Pointer Back
- Sub Si,Di ;Figure Number Characters
- Inc Si ;Adjust
- Mov Cx,Si ;Use As Counter
- Mov Ax,Es ;Transfer Es...
- Mov Ds,Ax ;To Ds
- Mov Si,Di ;Ds:Si Pts To Strx
- Rightend2: Les Di,Dword Ptr[Bp+12] ;Now Es:Di Pts To Return String
- Mov Es:[Di],Cl ;Set Return Descriptor
- Jcxz Rightend3 ;Jump Ahead If Null Strx
- Inc Di ;Forward Ptr
- Cld ;Direction Flag Forward
- Rep Movsb ;Move The String
- Rightend3: Pop Ds ;Restore Ds
- Mov Errreturn,Dl ;Set Errreturn
- Pop Bp ;Restore Bp And Quit
- Ret 6
- Rightend Endp
-
-
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Seekstring(Strx,Substrg: Stype; Startpt: Integer):Integer;
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- ;
- Seekstring Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Push Ds ;Save Turbo'S Ds
- Lds Si,Dword Ptr[Bp+12] ;Ds:Si Pts To Strx
- Les Di,Dword Ptr[Bp+8] ;Ds:Di Pts To Substrg
- Sub Cx,Cx ;Clear Cx
- Mov Cl,[Bp+6] ;Get Startpt
- Mov Bp,1 ;1 = Startpt Out Of Range
- Jcxz Seekstring11 ;Quit If Zero
- Mov Dl,Es:[Di] ;Substr Length In Dl
- Inc Di ;Di Pts 1St Chr Of Substr
- Inc Bp ;2 = Substrg Is Null
- Or Dl,Dl ;Substr Length Non-Zero?
- Jnz Seekstring21 ;Continue If So
- Seekstring11: Jmp Seekstring1 ;Error: Quit Routine
- Seekstring21: Mov Dh,[Si] ;Strx Length In Dh
- Dec Bp ;1 = Strx Is Null
- Or Dh,Dh ;Test For Null
- Jz Seekstring11 ;Quit If Null
- Mov Bl,Cl ;Startpt
- Add Bl,Dl ;Substrg Length
- Dec Bl ;Adjust
- Cmp Bl,Dh ;Compare To Strx Length
- Ja Seekstring11 ;Quit If Out Of Range
- Mov Bp,0 ;0 = No Error
- Mov Bl,Cl ;Startpt To Pos Counter
- Dec Bl ;Adjust
- Sub Dh,Cl ;Sub From Search Len
- Inc Dh ;Adjust
- Add Si,Cx ;Begin Search At Startpt
- Seekstring31: Mov Al,Es:[Di] ;Get Char From Of Substr
- Mov Ah,Al ;Copy In Ah
- Cmp Al,97 ;Low End Of Lower Case
- Jb Seekstring41 ;Jump If Below
- Cmp Al,122 ;Upper End Of Lower Case
- Ja Seekstring51 ;Neither Upper Nor Lower
- Sub Ah,32 ;Make Ah Upper Case
- Jmp Short Seekstring51 ;Go Test Both
- Seekstring41: Cmp Al,65 ;Low End Of Upper Case
- Jb Seekstring51 ;Neither Upper Nor Lower
- Cmp Al,90 ;High End Of Upper Case
- Ja Seekstring51 ;Neither Upper Nor Lower
- Add Ah,32 ;Make Ah Lower Case
- Seekstring51: Inc Bl ;Inc Strx Pos Counter
- Or Dh,Dh ;Counter = Zero?
- Jz Seekstring111 ;Quit If So
- Dec Dh ;Dec Length Counter
- Mov Bh,[Si] ;Get Char From Strx
- Cmp Bh,Al ;Test For Match
- Je Seekstring61 ;Jump If Found
- Cmp Bh,Ah ;2Nd Test For Match
- Je Seekstring61 ;Jump If Found
- Inc Si ;Forward Strx Ptr
- Jmp Short Seekstring51 ;Go Check Next Char
- Seekstring61: Cmp Dl,1 ;Single Char Substring?
- Je Seekstring1 ;If So, Not A Match
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Dl ;Cx = Substr Length
- Dec Cl ;1St Char Already Matched
- Push Si ;Save Strx Position
- Push Di ;Save Substr Position
- Seekstring71: Inc Si ;Pt To Nxt Char Of Strx
- Inc Di ;Pt To Nxt Char Of Substr
- Mov Al,Es:[Di] ;Get Char From Of Substr
- Mov Ah,Al ;Copy In Ah
- Cmp Al,97 ;Low End Of Lower Case
- Jb Seekstring81 ;Jump If Below
- Cmp Al,122 ;Upper End Of Lower Case
- Ja Seekstring91 ;Neither Upper Nor Lower
- Sub Ah,32 ;Make Ah Upper Case
- Jmp Short Seekstring91 ;Go Test Both
- Seekstring81: Cmp Al,65 ;Low End Of Upper Case
- Jb Seekstring91 ;Neither Upper Nor Lower
- Cmp Al,90 ;High End Of Upper Case
- Ja Seekstring91 ;Neither Upper Nor Lower
- Add Ah,32 ;Make Ah Lower Case
- Seekstring91: Mov Bh,[Si] ;Get Char From Strx
- Cmp Bh,Al ;Test For Match
- Je Seekstring101 ;Jump If Found
- Cmp Bh,Ah ;2Nd Test For Match
- Je Seekstring101 ;Jump If Found
- Pop Di ;Match Not Made
- Pop Si ;Restore Prior Ptrs
- Inc Si ;Forward Strx Ptr
- Jmp Short Seekstring31 ;Resume Search For 1St Ch
- Seekstring101: Loop Seekstring71 ;Go Compare Next Char
- Pop Di ;Substring Found!
- Pop Si ;Balance Stack
- Jmp Short Seekstring1 ;Go Set Return Value
- Seekstring111: Sub Bl,Bl ;Return 0
- Seekstring1: Sub Bh,Bh ;Return In Bl, Clear Bh
- Mov Ax,Bx ;Set Return Value
- Pop Ds ;Restore Ds
- Mov Bx,Bp ;Get Return Value
- Mov Errreturn,Bl ;Set Errreturn
- Pop Bp ;Restore Bp And Quit
- Ret 10
- Seekstring Endp
-
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Stringof(Substrg: Stype; Length: Integer): Stype;
- ;
- ;
- Data Segment
- Extrn Errreturn:Byte
- Data Ends
- ;
- Stringof Proc Far
- Push Bp ;Save Bp
- Mov Bp,Sp ;Set Up Stack Frame
- Mov Errreturn,1 ;1 = Error
- Push Ds ;Save Ds
- Les Di,Dword Ptr[Bp+12] ;Es:Di Pts To Return String
- Lds Si,Dword Ptr[Bp+8] ;Ds:Si Pts To Substring
- Mov Byte Ptr Es:[Di],0 ;Return Null String If Error
- Mov Cx,[Bp+6] ;Return String Length
- Jcxz Stringof3 ;Quit If Null
- Sub Ch,Ch ;255 Max
- Mov Dl,[Si] ;Get Substring Length
- Mov Dh,Dl ;Copy In Dh
- Or Dl,Dl ;Test For Zero Length
- Jz Stringof3 ;Quit If Zero
- Mov Es:[Di],Cl ;Set Return Strx Descriptor
- Mov Bx,Si ;Copy Strx Start Point
- Stringof1: Inc Di ;Forward Ret Strx Ptr
- Inc Si ;Forward Strx Ptr
- Mov Al,[Si] ;Get Character
- Mov Es:[Di],Al ;Write Character
- Dec Cx ;Finished Yet?
- Jz Stringof2 ;Quit If So
- Dec Dl ;End Of Strx Yet?
- Jnz Stringof1 ;Loop If Not
- Mov Dl,Dh ;Renew Strx Counter
- Mov Si,Bx ;Si Back To Start Of Strx
- Jmp Short Stringof1 ;Go Start Strx Again
- Stringof2: Pop Ds ;Restore Ds
- Dec Errreturn ;0 = No Error
- Jmp Short Stringof4 ;Jump Ahead
- Stringof3: Pop Ds ;Terminate With Error
- Stringof4: Pop Bp ;Restore Bp And Quit
- Ret 6
- Stringof Endp
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Procedure Uppercase(Var Strx: Stype);
- ;
- ;
- Uppercase Proc Far
- Mov Bx,Sp ;Bx Points To Stack
- Les Di,Ss:Dword Ptr[Bx+4] ;Es:Di Pts To String
- Sub Cx,Cx ;Clear Cx
- Mov Cl,Es:[Di] ;Get String Length
- Jcxz Uppercase3 ;Quit If Null
- Uppercase1: Inc Di ;Pt To Next Char Of Strx
- Cmp Es:Byte Ptr [Di],'Z' ;Test High Char
- Ja Uppercase2 ;Skip Ahead If Above
- Cmp Es:Byte Ptr [Di],'A' ;Test Low Char
- Jb Uppercase2 ;Skip Ahead If Below
- Sub Es:Byte Ptr [Di],32 ;Change The Char
- Uppercase2: Loop Uppercase1 ;Go Test Next Character
- Uppercase3: Ret 4
- Uppercase Endp
-
- ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- ;Function Wordcount(Strx: Stype): Integer;
- ;
- ;
- Wordcount Proc Far
- Mov Bx,Sp ;Bx Points To Stack
- Les Di,Ss:Dword Ptr[Bx+4] ;Point Es:Di To String
- Sub Dx,Dx ;Clear Dx As Counter
- Mov Cx,Dx ;Clear Cx
- Mov Cl,Es:[Di] ;Get String Descriptor
- Mov Al,32 ;Al Holds Space Char
- Wordcount1: Jcxz Wordcount3 ;Jump Ahead At Eol
- Inc Di ;Forward Pointer
- Dec Cx ;Dec Strx Counter
- Cmp Es:[Di],Al ;Char A Space?
- Je Wordcount1 ;Loop If So
- Inc Dx ;Word Starts -- Inc Ctr
- Wordcount2: Jcxz Wordcount3 ;Jump Ahead At Eol
- Inc Di ;Forward Pointer
- Dec Cx ;Dec Strx Counter
- Cmp Es:[Di],Al ;Char A Space?
- Je Wordcount1 ;Back To Spc Loop If So
- Jmp Short Wordcount2 ;Else Next Word Char
- Wordcount3: Mov Ax,Dx ;Set Return Value
- Ret 4
- Wordcount Endp
-
-
-
- Code Ends
-
- End
-
-
-
-