【问题标题】:Delphi inline assembler and class propertiesDelphi 内联汇编器和类属性
【发布时间】:2014-08-17 21:15:24
【问题描述】:

我正在尝试在汇编程序 (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:我不会故意处理此处未找到的情况

【问题讨论】:

  • 你不能从 asm 访问属性。当您放弃编译器时,您就放弃了该特权。

标签: delphi assembly properties basm


【解决方案1】:

您无法通过 Delphi 汇编程序访问对象属性!

Delphi编译器不错,我相信Delphi编译的代码也很快。

您的代码有错误,因为没有测试零计数值应该导致内存访问冲突的原因!

不要使用repne scasd,因为它很慢。

但是您可以手动破解代码来进行测试... :)

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;

【讨论】:

  • 我喜欢你在这里 const'ed 属性偏移的方式。然而,Scasd 的缓慢性尚待测量。
  • @Anton Duzenko:有几种方法。您可以使用调试器并单步执行 TList.add 函数到 FList[result] := Item 行,而不是将调试器窗口切换到 CPU 并读取 FList 索引。您还可以计算索引。检查 System.Classes 如何制作 TList 类。 FList 是数据类的第一个成员,因此索引为 4(0 索引为 ClassInfo),而 FCount 为 8,因为整数或指针的大小为 4 个字节。
  • 是的,我知道。现在我做了一个快速测试,根据我的真实数据(每个列表大约 64 个元素),你的代码比 scasd 快 4%。在大型列表(512+ 元素)上,scasd 稍微快一些。 delphi 的 IndexOf 比 asm 慢大约 30%。总而言之,你是第一名。
猜你喜欢
  • 1970-01-01
  • 2011-01-25
  • 2023-03-25
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 2019-05-11
  • 2012-10-20
  • 1970-01-01
相关资源
最近更新 更多