首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确保Delphi例程的16字节代码对齐?

如何确保Delphi例程的16字节代码对齐?
EN

Stack Overflow用户
提问于 2009-12-05 13:38:26
回答 2查看 1.6K关注 0票数 4

背景:

我有一个优化的Delphi/BASM例程单元,主要用于繁重的计算。其中一些例程包含内部循环,如果循环开始与DQWORD (16字节)边界对齐,则可以实现显着的加速。如果我知道常规入口点的对齐,我可以确保所讨论的循环按照需要对齐。

据我所见,Delphi编译器将过程/函数对齐到DWORD边界,例如向单元添加函数可能会更改后续函数的对齐。然而,只要我把例程的结尾按16的倍数,我就能确保后续的例程同样对齐--或者不对齐,这取决于第一个例程的对齐。因此,我试图将关键例程放在单元实现部分的开头,并在它们之前放置一些填充代码,以便第一个过程是对齐的。

如下所示:

代码语言:javascript
复制
interface

procedure FirstProcInUnit;

implementation

procedure __PadFirstProcTo16;
asm
    // variable number of NOP instructions here to get the desired code length
end;

procedure FirstProcInUnit;
asm //should start at DQWORD boundary
    //do something
    //padding to align the following label to DQWORD boundary
    @Some16BAlignedLabel:
        //code, looping back to @Some16BAlignedLabel
    //do something else
    ret #params
    //padding to get code length to multiple of 16
end;

initialization

__PadFirstProcTo16; //call this here so that it isn't optimised out
ASSERT ((NativeUInt(Pointer(@FirstProcInUnit)) AND $0F) = 0, 'FirstProcInUnit not DQWORD aligned');

end.

这有点让人头疼,但我可以在必要的时候让这类事情发挥作用。问题是,当我在不同的项目中使用这样的单元,或者对同一项目中的其他单元进行一些更改时,这仍然会破坏__PadFirstProcTo16本身的一致性。同样,用不同的编译器版本(例如D2009和D2010)重新编译同一个项目也会破坏对齐。所以,我发现做这类事情的唯一方法是手工操作,因为当项目的其余部分都处于最后的状态时,这几乎是最后要做的事情了。

问题1:

是否还有其他方法来达到所期望的效果,以确保(至少某些特定的)例程与DQWORD一致?

问题2:

影响编译器代码对齐的确切因素是哪些?(如何)我可以使用这些特定的知识来克服这里概述的问题?

假设为了这个问题,“不要担心代码对齐/相关的可能较小的速度效益”不是一个允许的答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-31 09:57:48

从Delphi开始,现在使用$CODEALIGN编译器指令很容易地解决了代码对齐问题(请参阅这个Delphi文档页面 )。

代码语言:javascript
复制
{$CODEALIGN 16}
procedure MyAlignedProc;
begin
..
end;
票数 7
EN

Stack Overflow用户

发布于 2009-12-06 02:34:41

您可以做的一件事是,在每个例程的末尾添加一个“魔术”签名,在一个明确的ret指令之后:

代码语言:javascript
复制
asm
  ...
  ret
  db <magic signature bytes>
end;

现在,您可以创建一个包含指向每个例程的指针的数组,在运行时扫描一次例程,以便找到每个例程的结束以及它的长度。然后,您可以使用VirtualAlloc将它们复制到使用PAGE_EXECUTE_READWRITE分配的新内存块中,确保每个例程从一个16字节的边界开始。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1852218

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档