gpt4 book ai didi

Delphi asm 到 purepascal

转载 作者:行者123 更新时间:2023-12-03 15:46:17 24 4
gpt4 key购买 nike

我正在尝试将 Delphi 5 代码迁移到 Delphi XE7-WIN64,但在以下 block 中遇到混合汇编代码的问题。我也是asm新手。

procedure IterateMenus(Func: Pointer; Menu1, Menu2: TElMenuItem);
var
I, J: Integer;
IIndex, JIndex: Byte;
Menu1Size, Menu2Size: Integer;
Done: Boolean;

function Iterate(var I: Integer; MenuItem: TElMenuItem; AFunc: Pointer): Boolean;
var
Item: TMenuItem;
begin
if MenuItem = nil then Exit;
Result := False;
while not Result and (I < MenuItem.Count) do
begin
Item := MenuItem[I];
if Item.GroupIndex > IIndex then Break;
asm
MOV EAX,Item
MOV EDX,[EBP+8]
PUSH DWORD PTR [EDX]
CALL DWORD PTR AFunc
ADD ESP,4
MOV Result,AL
end;
Inc(I);
end;
end;

begin
I := 0;
J := 0;
Menu1Size := 0;
Menu2Size := 0;
if Menu1 <> nil then
Menu1Size := Menu1.Count;
if Menu2 <> nil then
Menu2Size := Menu2.Count;
Done := False;
while not Done and ((I < Menu1Size) or (J < Menu2Size)) do
begin
IIndex := High(Byte);
JIndex := High(Byte);
if (I < Menu1Size) then
IIndex := Menu1[I].GroupIndex;
if (J < Menu2Size) then
JIndex := Menu2[J].GroupIndex;
if IIndex <= JIndex then
Done := Iterate(I, Menu1, Func)
else
begin
IIndex := JIndex;
Done := Iterate(J, Menu2, Func);
end;
while (I < Menu1Size) and (Menu1[I].GroupIndex <= IIndex) do
Inc(I);
while (J < Menu2Size) and (Menu2[J].GroupIndex <= IIndex) do
Inc(J);
end;
end;

我正在尝试将asm block 转换为purepascal,因为delphi x64不允许混合代码并且asm对程序员不友好。

据我了解,Item 的地址已移至 EAX,那我什么也得不到。 EBP从哪里来?什么是 ESP 和 AL?上面的代码片段来自 ELPack 的 ELmenus.pas。

那么基本上,asm 代码块的 PurePascal 版本是什么?

为了好玩,我找到了这个

procedure TElMenuItem.UpdateItems;

function UpdateItem(MenuItem: TElMenuItem): Boolean;
begin
Result := False;
IterateMenus(@UpdateItem, MenuItem.FMerged, MenuItem);
MenuItem.SubItemChanged(MenuItem, MenuItem, True);
end;

begin
IterateMenus(@UpdateItem, FMerged, Self);
end;

procedure TElMenuItem.PopulateMenu;
var
MenuRightToLeft: Boolean;

function AddIn(MenuItem: TElMenuItem): Boolean;
begin
MenuItem.AppendTo(FHandle, MenuRightToLeft);
Result := False;
end;

begin // all menu items use BiDiMode of their root menu
{$ifdef VCL_4_USED}
MenuRightToLeft := (FMenu <> nil) and FMenu.IsRightToLeft;
{$else}
MenuRightToLeft := false;
{$endif}
IterateMenus(@AddIn, FMerged, Self);
end;

最佳答案

我猜最初的程序员编写了奇怪的代码来绕过不支持本地函数指针的Delphi。 (这是一个有时让我恼火的限制。)

以下内容应该有效。 (虽然我对我的 asm 不太清楚。我首先会通过在 D5 中单步执行调试器来测试 asm 代码,以确认行 CALL DWORD PTR AFunc 正在传递我期望的值。)

1) 删除函数指针类型并移动 UpdateItem,使其不再是本地的。

type
TMenuOperation = function (AMenuItem: TElMenuItem): Boolean;
//Or if you want to move the UpdateItem to a method of a class..
//TMenuOperation = function (AMenuItem: TElMenuItem): Boolean of object;

2) 进行以下更改:

procedure IterateMenus(Func: Pointer; Menu1, Menu2: TElMenuItem);
//becomes
procedure IterateMenus(Func: TMenuOperation; Menu1, Menu2: TElMenuItem);

//...

function Iterate(var I: Integer; MenuItem: TElMenuItem; AFunc: Pointer): Boolean;
var
Item: TMenuItem;
//becomes
function Iterate(var I: Integer; MenuItem: TElMenuItem; AFunc: TMenuOperation): Boolean;
var
Item: TElMenuItem;

//...

Item := MenuItem[I];
//becomes
Item := MenuItem[I] as TElMenuItem;

3) 最后汇编程序 block 变为:

Result := AFunc(Item);

关于Delphi asm 到 purepascal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27601831/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com