{ Segmented 16 & Flat 32 compatible the name 'Seg16' should be defined in 16bit segment mode } {$O+,F+} Unit StrTrs32; INTERFACE const cDecimal='0123456789'; cHexadecimal=cDecimal+'ABCDEF'; type tDWord={$IfDef Seg16}array[0..1] of word{$Else} cardinal {$EndIf NDef Seg16}; function Word2Str(num:word; const chars:shortstring):shortstring; {$IfNDef Seg16} pascal; {$EndIf NDef Seg16} function DWord2Str(num:Tdword; const chars:shortstring):shortstring; function AddNumberTail(Number:Word; const CommonPart:string; const TailFor1,TailFor24,TailForOthers:string):string; function DWord2HexStr(num:Tdword):string; IMPLEMENTATION { USES StrScan, xStrings;} function DWord2HexStr(num:Tdword):string; begin DWord2HexStr:=DWord2Str(num, cHexadecimal); end; function DWord2Str(num:Tdword; const chars:shortstring):shortstring; {$IfDef Seg16} external; {$L DW2Str} {$Else} assembler; asm push ebx; push esi; push edi mov edi,@Result; push edi inc edi { EDI->Result[1]} mov esi,Chars; { AL := Length(chars); ESI->Chars[1] } movzx ebx,byte([esi]) { EBX := Length(chars) } inc esi cmp byte([esi]),2; jb @EndLoop { if Length(chars)<2 then exit procedure} mov ecx,esi { CX := OFFSET chars[1] } // { EAX := num } @Loop: xor edx,edx { convert EAX to doubleword in EDX:EAX} div ebx { EDX:= EAX mod EBX; EAX := EAX div EBX } add edx,ecx; mov esi,edx { ESI -> next char of converting string} movsb { Store next char of converting string} or eax,eax; jnz @Loop; @EndLoop: mov esi,edi; pop edi { mov edi,@Result; } mov ecx,esi; sub ecx,edi; dec cl; mov al,cl stosb { Store length of returned string} mov ebx,-1; xchg esi,edi; shr ecx,1; jecxz @End @loop1: { Make Reverse String} dec edi mov al,[edi]; movsb; mov [esi][ebx],al dec edi loop @loop1 @End: pop edi; pop esi; pop ebx end; {$EndIf} function Word2Str; assembler; { Subroutine to convert a binary number to a text string. The leading zeros are omitted (only non zero digits are returned). EXAMPLES: xstring:=Word2Str(34567,'0123456789ABCDEF'); - example of converting to hex representation; xstring:=Word2Str(34567,'01'); - example of converting to bihary representation; xstring:=Word2Str(34567,'0123456789'); - example of converting to decimal representation; NUM := number to convert; CHARS := string contained the valid chars of symbol number representation ordered in ascending direction; Length(CHARS) used as BASE of converting; Return : 'ccccc' - converted string if sucsessful, '' - empty string if error ( Length(chars)<2 ). } asm {$IfDef Seg16} push ds les di,@Result; inc di lds si,chars; cld; lodsb { AL := Length(chars) } cmp al,2; jb @EndLoop { if Length(chars)<2 then exit procedure} mov bl,al; xor bh,bh { BX := Length(chars) } mov cx,si { CX := OFFSET chars[1] } mov ax,num { AX := num } @Loop: xor dx,dx { convert AX to doubleword in DX:AX} div bx { DX:= AX mod BX; AX := AX div BX } add dx,cx; mov si,dx { DS:SI -> next char of converting string} movsb { Store next char of converting string} or ax,ax; jnz @Loop; @EndLoop: mov si,di; les di,@Result; mov cx,si; sub cx,di; dec cl; mov al,cl stosb { Store length of returned string} mov bx,-1; xchg si,di; shr cx,1; jcxz @End @loop1: { Make Reverse String} dec di mov al,es:[di]; SEGES movsb; mov es:[si][bx],al dec di loop @loop1 @End: pop ds {$Else} push ebx; push esi; push edi mov edi,@Result; inc edi mov esi,chars; cld; lodsb { AL := Length(chars) } cmp al,2; jb @EndLoop { if Length(chars)<2 then exit procedure} mov bl,al; xor bh,bh { BX := Length(chars) } mov ecx,esi { CX := OFFSET chars[1] } mov ax,num { AX := num } @Loop: xor dx,dx { convert AX to doubleword in DX:AX} div bx { DX:= AX mod BX; AX := AX div BX } add edx,ecx; mov esi,edx { ESI -> next char of converting string} movsb { Store next char of converting string} or ax,ax; jnz @Loop; @EndLoop: mov esi,edi; mov edi,@Result; mov ecx,esi; sub ecx,edi; dec cl; mov al,cl stosb { Store length of returned string} mov ebx,-1; xchg esi,edi; shr ecx,1; jecxz @End @loop1: { Make Reverse String} dec edi mov al,[edi]; movsb; mov [esi][ebx],al dec edi loop @loop1 @End: pop edi; pop esi; pop ebx {$EndIf} end; function AddNumberTail(Number:Word; const CommonPart:string; const TailFor1,TailFor24,TailForOthers:string):string; var s:string[64]; len:Byte; ch:Char; begin Str(Number,s); len:=Length(s); if (len>1) and (s[Pred(len)]='1') then ch:='9' else ch:=s[len]; s:=s+' '+CommonPart; case ch of '1': s:=s+TailFor1; '2'..'4': s:=s+TailFor24; else s:=s+TailForOthers; end; AddNumberTail:=s end; END.