jus*_*tyy 7 delphi assembly sse basm
我试图运行以下,
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;
Run Code Online (Sandbox Code Playgroud)
它提供了对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, [a]
movaps xmm1, [b]
addps xmm0, xmm1
movaps [@result], 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.
Run Code Online (Sandbox Code Playgroud)
如果没有添加"使用窗口",一切都很好.如果'使用窗口',那么它将在c:= add4(a,b)但不在test()中抛出异常.
谁能解释一下?
编辑 它现在对我来说都很有意义.Delphi XE3的结论 - 64位是
您需要数据按 16 字节对齐。这需要一些照顾和关注。您可以确保堆分配器与 16 字节对齐。但是您无法确保编译器会对堆栈分配的变量进行 16 字节对齐,因为您的数组的对齐属性为 4,即其元素的大小。在其他结构内声明的任何变量也将具有 4 字节对齐。这是一个很难清除的障碍。
我认为您无法在当前可用的编译器版本中解决您的问题。至少不会,除非你放弃堆栈分配的变量,我猜这是一颗难以下咽的药丸。您可能会幸运地使用外部汇编器。