私は以下を実行しようとしていました、
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でAccess Violation が発生します。私の知る限り、メモリ位置が 16-align の場合、movapsは信頼できます。ムーブアップの場合は問題ありません (整列は必要ありません)。
私の質問は、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.
「ウィンドウを使用」が追加されていない場合は、すべて問題ありません。「ウィンドウを使用」の場合、c := add4(a, b)で例外がスローされますが、 test()ではスローされません。
誰がこれを説明できますか?
編集 して、今ではすべてが理にかなっています。Delphi XE3 - 64 ビットの結論は次のとおりです。
- X64 のスタック フレームは (必要に応じて) 16 バイトに設定され、{$CODEALIGN 16} は proc/fun のコードを 16 バイトに揃えます。
- 動的配列はヒープに存在し、SetMinimumBlockAlignment(mba16byte) を使用して 16 に整列するように設定できます
- ただし、スタック var は常に 16 バイト アラインされているとは限りません。