[Back to MATH SWAG index] [Back to Main SWAG index] [Original]
{
Just for fun, I sat down last night and generated an inline asm version
of the C code I posted that permuted character strings. This version
uses about 90 clock cycles/call on a 486 and 60 on a Pentium, i.e.
one microsecond/call on my P5-60: (The average time is very nearly
independent of the length of the string.)
From: terjem@hda.hydro.com (Terje Mathisen)
}
{$R-,S-}
Program Permutate;
Function Permute(var a; alen : word): Boolean;
Assembler;
asm
push ds { BX -> beginning of array }
lds bx,[a]
mov di,[alen] { Array length }
xor cx,cx { Return value = False }
lea si,[di+bx-2]{ SI -> one character before last }
lea di,[di+bx-1]{ DI -> last position in a[] }
@loop1:
cmp si,bx { Check if we've gotten to the beginning of the array!}
jb @reverse { Yes, so no permutation found, return reversed array!}
mov ax,[si] { Get another pair of bytes from the end }
dec si
cmp al,ah
jae @loop1 { Loop until a[si] < a[si+1] }
{ We have found a pair of bytes where the first is less than
the second, which means that there exists at least one more
permutation of the a[] array.
}
mov bx,di { BX -> Last byte in a[] }
inc si { SI was decremented one extra time, adjust back }
mov cl,True { Return value = True }
{ Find the last byte which is > al (a[si]) }
@loop2:
mov dl,[bx]
dec bx
cmp dl,al
jbe @loop2
{ Swap the two positions found: }
mov [si],dl
mov [bx+1],al
jmp @reverse { Reverse the rest of the array! }
@loop3:
mov al,[si]
mov dl,[di]
mov [di],al
dec di
mov [si],dl
@reverse:
inc si
cmp si,di
jb @loop3
mov ax,cx
pop ds
end;
var
test, org : String;
n : LongInt;
begin
org := ParamStr(1);
test := org;
n := 0;
if ParamCount > 1 then begin {Verbose version }
repeat
WriteLn(n:10,' ',test);
Inc(n);
until not Permute(test[1],Length(test));
WriteLn(n:10,' ',test);
end
else begin
repeat
Inc(n);
until not Permute(test[1],Length(test));
WriteLn(n,' permutations of ',org,' found!');
end;
end.
[Back to MATH SWAG index] [Back to Main SWAG index] [Original]