The Delphi Bug List

Entry No.
683
コンパイラ - コード生成
EAXレジスタの変更がforループを壊す
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/A Absent Absent Absent Absent Absent Absent Absent Absent Absent Absent Unknown Exists Exists Unknown
解説
Reported by Nick Walter; checked by Jordan Russell
Delphiのヘルプより:
asm 文は EDI,ESI,ESP,および EBX レジスタを保持しなければなりませんが,EAX,ECX,および EDX レジスタは自由に変更できます。
Delphi 6 では、asm 文の中でEAXレジスタを使用すると問題が発生します。
procedure Delphi6EAXBug; // Delphi6では無限ループになります
var
  i: integer;
begin
  for i := 0 to 15 do
    asm
      mov eax,2
    end;
end;
解決策 / 回避方法
回避方法:
procedure Delphi6EAXBug;
var
  i: integer;
begin
  for i := 0 to 15 do
    asm
      push eax
      mov eax,2
      pop eax
    end;
end;
ユーザーからのコメント
Abel Belzunces
13 Feb 2002  11:39 AM GMT
これはバグではありません。Delphiはデフォルトで最適化を行い、高速化のためにレジスタを使用します。

Delphi上で次のように見えるコード、

begin
for i:=0 to 15 do
mov eax,2
end;

これは、以下のようなアセンブラコードを生成します。

asm
mov eax,15
@1:
mov eax,2
dec eax
jnz @1
end;

したがって、二つの選択肢があります。最適化を無効にするか、ループ内で asm と Object Pascal を混在させないことです。
Ficedula
16 Feb 2002  07:58 PM GMT
ドキュメントに EAX を自由に変更できると書かれているのですから、これはバグです。コンパイラが既にレジスタを使用しており、なおかつそのレジスタがASMの中でも使用されているのなら、コンパイラはそのレジスタを push/pop するべきす。さもなければ、EAXを自由に変更できると主張するべきではないでしょう。
Latest update of this entry: 2002-04-05
本家 The Delphi Bug List のエントリーはこちら
The Delphi Bug List 日本語訳 へ