我试图运行以下,
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(),这个例子不起作用.