7

私は以下を実行しようとしていました、

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 ビットの結論は次のとおりです。

  1. X64 のスタック フレームは (必要に応じて) 16 バイトに設定され、{$CODEALIGN 16} は proc/fun のコードを 16 バイトに揃えます。
  2. 動的配列はヒープに存在し、SetMinimumBlockAlignment(mba16byte) を使用して 16 に整列するように設定できます
  3. ただし、スタック var は常に 16 バイト アラインされているとは限りません
4

3 に答える 3

1

これを使用して、組み込みメモリ マネージャーに 16 バイト アラインメントを割り当てるようにします。

SetMinimumBlockAlignment(mba16Byte);

また、私の知る限り、「レジスタ」と「アセンブラー」はどちらも冗長なディレクティブであるため、コードからそれらをスキップできます。

--

編集:これはx64用であると述べています。x64用にコンパイルされたDelphi XE2で次のことを試したところ、ここで動作します。

program Project3;

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 f();
var
  v1,v2 : vector;
begin
  v1[1] := 1;
  v2[1] := 1;
  v1 := add4(v1,v2);
end;

begin
  {$ifndef cpux64}
  {$MESSAGE FATAL 'this example is for x64 target only'}
  {$else}
  f();
  {$endif}
end.
于 2013-04-04T07:38:35.347 に答える