- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将 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/
我正在尝试将 Delphi 5 代码迁移到 Delphi XE7-WIN64,但在以下 block 中遇到混合汇编代码的问题。我也是asm新手。 procedure IterateMenus(Func
我正在尝试将一些 Delphi 5 代码转换为 Delphi XE7-x64,但我陷入了以下代码: function FindScanline(Source : Pointer; MaxLen : C
我是一名优秀的程序员,十分优秀!