[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]
procedure CopySubStr( Str1: string; start, nrchars: byte; var Str2: string );
assembler;
{ copy part of Str1 (beginning at start for nrchars) to Str2
if start > length of Str1, Str2 will contain a empty string.
if nrchars specifies more characters than remain starting at the
start position, Str2 will contain just that remainder of Str1. }
asm
{ setup }
LDS SI,Str1 { load in DS:SI pointer to str1 }
CLD { string operations forward }
LES DI,Str2 { load in ES:DI pointer to str2 }
MOV AH,[SI] { length str1 --> AH }
AND AH,AH { length str1 = 0? }
JE @null { yes, empty string in Str2 }
MOV BL,[start] { starting position --> BL }
CMP AH,BL { start > length str1? }
JB @null { yes, empty string in Str2 }
{ start + nrchars - 1 > length str1? }
MOV AL,[nrchars] { nrchars --> AL }
MOV DH,AL { nrchars --> DH }
ADD DH,BL { add start }
DEC DH
CMP AH,DH { nrchars > rest of str1? }
JB @rest { yes, copy rest of str1 }
JMP @copy
@null:
MOV AL,0 { return a empty string }
JMP @done
@rest:
SUB AH,BL { length str1 - start }
INC AH
MOV AL,AH
@copy:
MOV CL,AL { how many chars to copy }
XOR CH,CH { clear CH }
XOR BH,BH { clear BH }
ADD SI,BX { starting position }
MOV DX,DI { save pointer to str2 }
INC DI
REP MOVSB { copy part str1 to str2 }
MOV DI,DX { restore pointer to str2 }
@done:
MOV [DI],AL { overwrite length byte of str2 }
@exit:
end { CopySubStr };
procedure StrCopy( var Str1, Str2: string ); assembler;
{ copy str1 to str2 }
asm
LDS SI,Str1 { load in DS:SI pointer to str1 }
CLD { string operations forward }
LES DI,Str2 { load in ES:DI pointer to str2 }
XOR CH,CH { clear CH }
MOV CL,[SI] { length str1 --> CX }
INC CX { include length byte }
REP MOVSB { copy str1 to str2 }
@exit:
end { StrCopy };
function StrPos( var str1, str2: string ): byte; assembler;
{ returns position of the first occurrence of str1 in str2 }
{ return value in AX }
{ str1 - string to search for }
{ str2 - string to search in }
asm
CLD { string operations forward }
LES DI,Str2 { load in ES:DI pointer to str2 }
XOR CH,CH { clear CH }
MOV CL,[DI] { length str2 --> CX }
AND CX,CX { length str2 = 0? }
JZ @Negatief { length str2 = 0, nothing to search in }
INC DI { make DI point to the 1st char of str2 }
LDS SI,Str1 { load in DS:SI pointer to str1 }
LODSB { load in AL length str1 }
AND AL,AL { length str1 = 0? }
JZ @Negatief { length str1 = 0, nothing to search for }
MOV AH,AL { length str1 --> AH }
DEC AH { 1st char need not be compared again }
LODSB { load in AL 1st character of str1 }
@Start:
REPNE SCASB { scan for next occurrence 1st char in str2 }
JNE @Negatief { no success }
CMP CL,AH { length str1 > # chars left in str2 ? }
JB @Negatief { yes, str1 not in str2 }
MOV DX,SI { pointer to 2nd char in str1 --> DX }
MOV BX,CX { number of chars in str2 to go --> BX }
MOV CL,AH { length str1 --> CL }
REPE CMPSB { compare until characters don't match }
JE @Positief { full match }
SUB SI,DX { current SI - prev. SI = # of chars moved }
SUB DI,SI { reconstruct DI }
MOV SI,DX { restore pointer to 2nd char in str1 }
MOV CX,BX { number of chars in str2 to go --> BX }
JMP @Start { scan for next occurrence 1st char in str2 }
@Negatief:
XOR AX,AX { str1 is not in str, result 0 }
JMP @Exit
@Positief:
XOR AH,AH { clear AH }
LES DI,Str2 { load in ES:DI pointer to str2 }
MOV AL,[DI] { length str2 --> AX }
SUB AX,BX { start position of str1 in str2 }
@Exit: { we are finished. }
end { StrPos };
procedure Trim( var Str: string ); assembler;
{ remove leading and trailing white space from str }
asm
{ setup }
LDS SI,Str { load in DS:SI pointer to Str }
MOV AX,DS { Set ES to same segment as DS }
MOV ES,AX { Set ES to same segment as DS }
MOV AL,[SI] { length Str --> AL }
AND AL,AL { length Str = 0? }
JZ @exit { yes, nothing to do }
MOV DI,SI { pointer to Str --> DI }
MOV AH,AL { length Str --> AH }
{ remove trailing white space }
XOR CH,CH { clear CH }
MOV CL,AH { length Str --> CX }
ADD SI,CX { start with last character }
@start1:
MOV AL,[SI] { character --> AL }
CMP AL,20H { no white space }
JA @stop1 { last non-blank character found }
DEC SI { count down SI }
DEC CL { count down CX }
AND CL,CL { more characters left? }
JZ @stop1 { no, done }
JMP @start1 { try again }
@stop1:
AND CL,CL { length Str = 0? }
JZ @done { string is empty, done }
{ look for leading white space }
MOV SI,DI { pointer to Str --> SI }
@start2:
INC SI { next character }
MOV AL,[SI] { character --> AL }
CMP AL,20H { no white space }
JA @stop2 { first non-blank character found }
DEC CL { count down }
AND CL,CL { more characters left? }
JZ @stop2 { no, done }
JMP @start2 { try again }
@stop2:
MOV DX,SI { difference between SI and DI gives }
SUB DX,DI { position first non-blank character }
CMP DX,1 { first character non-blank? }
JE @done { yes, done }
{ remove leading white space }
CLD { string operations forward }
MOV BX,CX { save length Str }
MOV DX,DI { save pointer to Str }
INC DI { don't overwrite length byte of Str }
REP MOVSB { move remaining part of Str }
MOV DI,DX { restore pointer to Str }
MOV CX,BX { restore length Str }
@done:
MOV [DI],CL { overwrite length byte of Str }
@exit:
end { Trim };
procedure RTrim( var Str: string ); assembler;
{ remove trailing white space from str }
asm
{ setup }
LDS SI,Str { load in DS:SI pointer to Str }
MOV AL,[SI] { length Str --> AL }
AND AL,AL { length Str = 0? }
JZ @exit { yes, exit }
MOV DI,SI { pointer to Str --> DI }
MOV AH,AL { length Str --> AH }
{ remove trailing space }
STD { SeT Direction flag --> backwards }
XOR CH,CH { clear CH }
MOV CL,AH { length Str --> CX }
ADD SI,CX { start with last character }
@start:
MOV AL,[SI] { character --> AL }
CMP AL,20H { no white space }
JA @stop { last non-blank character found }
DEC SI { count down }
DEC CL { count down }
AND CL,CL { more characters left? }
JZ @stop { no, done }
JMP @start { try again }
@stop:
MOV [DI],CL { overwrite length byte of Str }
@exit:
end { RTrim };
procedure LTrim( var Str: string ); assembler;
{ remove leading white space from str }
asm
{ setup }
LDS SI,Str { load in DS:SI pointer to Str }
MOV AL,[SI] { length Str --> AL }
AND AL,AL { length Str = 0? }
JZ @exit { yes, nothing to do }
MOV DI,SI { pointer to Str --> DI }
XOR CH,CH { clear CH }
MOV CL,AL { length Str --> CX }
{ look for leading white space }
@start:
INC SI { next character }
MOV AL,[SI] { character --> AL }
CMP AL,20H { no white space }
JA @stop { first non-blank character found }
DEC CL { count down }
AND CL,CL { more characters left? }
JZ @nullstr { no, done }
JMP @start { try again }
@nullstr:
MOV CL,0 { null string }
JMP @done { we're done }
@stop:
MOV DX,SI { difference between SI and DI gives }
SUB DX,DI { position first non-blank character }
CMP DX,1 { first character non-blank? }
JE @exit { yes, exit }
{ remove leading white space }
CLD { string operations forward }
MOV DX,CX { save length Str }
MOV BX,DI { save pointer to Str }
INC DI { don't overwrite length byte of Str }
REP MOVSB { move remaining part of Str }
MOV DI,BX { restore pointer to Str }
MOV CX,DX { restore length Str }
@done:
MOV [DI],CL { overwrite length byte of Str }
@exit:
end { LTrim };
[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]