home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
tpfast.zip
/
FASTSTR.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-09-26
|
51KB
|
943 lines
; _______________________________________________________________
; | |
; | 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