Inline Assemblers and Delphi Class Properties
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 properties like Count or List directly. I understand why the compiler refuses to grant access to the private fields FCount and FList, but how do I access the corresponding properties? Count, Self.Count and [eax] .Count all give inline assembly error.
JIC: I am not handling the not found situation here by intent
source to share
You cannot access a property of an object through Delphi assembler!
The Delphi compiler is good and Delphi compiled the code. I also believe very quickly.
Your code has a bug because it doesn't check for a value of zero, which should break memory access!
Do not use repne scasd
because it is slow.
However, you can hack the code manually to execute the 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;
source to share