如何在Delphi XE3中使用align-data-move SSE?

我试图运行以下,
type
  Vector = array [1..4] of Single;

{$CODEALIGN 16}
function add4(const a,b: Vector): Vector; register; assembler;
asm
  movaps xmm0,[a]
  movaps xmm1,[b]
  addps xmm0,xmm1
  movaps [@result],xmm0
end;

它提供了对movaps的访问冲突,据我所知,如果内存位置为16对齐,则可以信任movaps.如果是movups(不需要对齐),它没有问题.

所以我的问题是,在Delphi XE3中,{$CODEALIGN}在这种情况下似乎不起作用.

编辑

很奇怪……我尝试了以下几点.

program Project3;

{$APPTYPE CONSOLE}

uses
  windows;  // if not using windows,no errors at all

type
  Vector = array [1..4] of Single;

function add4(const a,b: Vector): Vector;
asm
  movaps xmm0,xmm0
end;

procedure test();
var
  v1,v2: vector;
begin
  v1[1] := 1;
  v2[1] := 1;
  v1 := add4(v1,v2);  // this works
end;

var
  a,b,c: Vector;

begin
  {$ifndef cpux64}
    {$MESSAGE FATAL 'this example is for x64 target only'}
  {$else}
  test();
  c := add4(a,b); // throw out AV here
  {$endif}
end.

如果没有添加“使用窗口”,一切都很好.
如果’使用窗口’,那么它将在c:= add4(a,b)抛出异常但不在test()中抛出异常.

谁能解释一下?

编辑
现在,这一切对我都有意义. Delphi XE3的结论 – 64位是

> X64的堆栈帧设置为16字节(根据需要),{$CODEALIGN 16}将proc / fun的代码与16字节对齐.
>动态数组存在于堆中,可以使用SetMinimumBlockAlignment(mba16byte)将其设置为对齐16
>但是,堆栈变量并不总是16字节对齐,例如,如果在上面的示例中声明v1,v2之前的整数变量,test(),这个例子不起作用.

解决方法

您需要将数据对齐16字节.这需要一些关心和关注.您可以确保堆分配器对齐到16个字节.但是您无法确保编译器将16字节对齐堆栈分配的变量,因为您的数组的对齐属性为4,即元素的大小.在其他结构中声明的任何变量也将具有4字节对齐.这是一个很难解决的障碍.

我不认为您可以在当前可用的编译器版本中解决您的问题.至少除非你放弃堆叠分配的变量,我猜这些变量太难以吞下.你可能会对外部汇编程序有一些好运.

相关文章

ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c++ 调用, 抽空研究了一下该库的最新版 ,把...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI) 2个指针寄...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的功能是:将源操作数送到目的操作数中,即:...
有三个API函数可以运行可执行文件WinExec、ShellExecute和CreateProcess。 1.CreateProcess因为使用复杂...
API原型: Declare Function MoveFileEx& Lib "kernel32" Alias "MoveFileExA" (By...