我试图在汇编程序(XE3)中重写TList.IndexOf方法。这是我的代码
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;
当然我想直接使用Count或List这样的属性。我理解为什么编译器拒绝提供对私有字段FCount和FList的访问,但是如何访问相应的属性? Count,Self.Count和[eax] .Count都会给出内联汇编程序错误。
JIC:我没有按意图处理未找到的情况
答案 0 :(得分:5)
您无法通过Delphi汇编程序访问对象属性!
Delphi编译器很好,我相信的Delphi编译代码也很快。
您的代码有错误,因为没有测试零计数,以确定应该导致内存访问违规的内容!
不要使用repne scasd
,因为它很慢。
但是你可以破解代码manualy进行测试......:)
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;