I am trying to rewrite the TList.IndexOf method in assembler (XE3). Here is my code
function TFastList.IndexOfAsm(Item: Pointer): Integer;
{var
P: PPointer;
begin
P := Pointer(FList);
for Result := 0 to FCount - 1 do
begin
if P^ = Item then
Exit;
Inc(P);
end;
Result := -1;}
var
FCnt, rslt: Integer;
FData: Pointer;
begin
FCnt := Count;
FData := List;
asm
push edi
mov ecx, FCnt
mov edi, FData
mov eax, Item
repne scasd
mov eax, FCnt
sub eax, ecx
dec eax
mov rslt, eax
pop edi
end;
Result := rslt;
end;
Naturally I would like to use the properties like Count or List directly. I understand why the compiler refuses to give access to private fields FCount and FList, but how do I access the corresponding properties? Count, Self.Count, and [eax].Count all give the inline assembler error.
JIC: I don't handle the not found situation here by intent
You can't access the object property via Delphi assembler!
Delphi compiler is good and Delphi compiled code I belive is also very fast.
Your code has mistake because doesn't test zero count velue what should cause memory access violation!
Do not use repne scasd
because it is slow.
However you can hack code manualy to make test... :)
function TFastList.IndexOfAsm(Item: Pointer): Integer;
//eax = self
//edx = Item
{var
P: PPointer;
begin
P := Pointer(FList);
for Result := 0 to FCount - 1 do
begin
if P^ = Item then
Exit;
Inc(P);
end;
Result := -1;}
const
FItems = 4; //data offset of FItems
FCount = 8; //data offset of FCount
asm
mov ecx, [eax].FItems //ecx = @FItems
mov eax, [eax].FCount //eax = FCount
dec eax //test zero count!
js @Exit //if count was 0 then exit as -1
@Loop: //repeat
cmp Item, [ecx + eax * 4]
jz @Exit
dec eax
jns @Loop //until eax < 0 (actually -1)
@Exit:
end;