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を自由に変更できると主張するべきではないでしょう。
|
|