特定のケースでは、Delphi 5が無効なアセンブリコードを生成することがわかりました。私は一般的にどのような場合に理解できません。非常に奇妙な最適化が発生するため、以下の例ではアクセス違反が発生します。レコードまたは配列内のバイトについてDelphiは、このバイトの後にデータがある場合(正確にはdwordを3回押す必要がある)正しく動作するpush dword [...]、pop ebx、mov ..、blを生成しますが、失敗しますデータにアクセスできない場合私は具体的にエラーが発生したwin32のバーチャル*機能 Delphiの "push dword"バグを回避するにはどうすればよいですか?
とここに厳密な境界をエミュレートするときFeedBytesToClass手続きの内側にアクセスされたブロックから最後のバイト。また、remove actionFlag変数のオブジェクトプロパティの代わりにデータ配列を使用するようなものを変更しようとすると、Delphiは正しいアセンブリ命令を生成します。 IビットマップビットのRGBデータへのアクセスを使用した場合const
BlockSize = 4096;
type
TSomeClass = class
private
fBytes: PByteArray;
public
property Bytes: PByteArray read fBytes;
constructor Create;
destructor Destroy;override;
end;
constructor TSomeClass.Create;
begin
inherited Create;
GetMem(fBytes, BlockSize);
end;
destructor TSomeClass.Destroy;
begin
FreeMem(fBytes);
inherited;
end;
procedure FeedBytesToClass(SrcDataBytes: PByteArray; Count: integer);
var
j: integer;
Ofs: integer;
actionFlag: boolean;
AClass: TSomeClass;
begin
AClass:=TSomeClass.Create;
try
actionFlag:=true;
for j:=0 to Count-1 do
begin
Ofs:=j;
if actionFlag then
begin
AClass.Bytes[Ofs]:=SrcDataBytes[j];
end;
end;
finally
AClass.Free;
end;
end;
procedure TForm31.Button1Click(Sender: TObject);
var
SrcDataBytes: PByteArray;
begin
SrcDataBytes:=VirtualAlloc(Nil, BlockSize, MEM_COMMIT, PAGE_READWRITE);
try
if VirtualLock(SrcDataBytes, BlockSize) then
try
FeedBytesToClass(SrcDataBytes, BlockSize);
finally
VirtualUnLock(SrcDataBytes, BlockSize);
end;
finally
VirtualFree(SrcDataBytes, MEM_DECOMMIT, BlockSize);
end;
end;
は、最初にエラーが発生しましたが、コードは複雑すぎあるので、私はこの断片にそれを狭く。
そこで問題は、ここではそのDelphiの農産物プッシュを作る具体的な、ポップ、MOVの最適化は何かということです。私はこのような副作用を一般的に避けるためにこれを知る必要があります。
Delphi5のすべてのアップグレードをインストールしましたか? – smok1
はい、あります。実際、このバグは依然としてDelphiに存在する可能性があります。これは、globalallocは後で余分なバイトと内部getmemを頻繁に割り当てるためです。 – Maksee
QCにこのバグはありますか?これは、それが新しいバージョンで修正されているかどうか、また回避策があるかもしれないことを教えてくれます。 –