我对Delphi 10.2 Pascal编程语言中的特定编程问题有疑问.
StringOfChar和FillChar在2012年之前发布的CPU上的Win64 Release版本下无法正常工作.
FillChar的预期结果只是在给定的内存缓冲区中重复8位字符的简单序列.
StringOfChar的预期结果是相同的,但结果存储在字符串类型中.
但实际上,当我在10.2版本的Delphi中编译我们在10.2之前的Delphi中运行的应用程序时,我们为Win64编译的应用程序在2012年之前发布的CPU上停止正常工作.
StringOfChar和FillChar不能正常工作 - 它们返回一串不同的字符,虽然是重复的模式 - 而不仅仅是它们应该具有相同字符的序列.
这是足以证明问题的最小代码.请注意,序列的长度应至少为16个字符,并且字符不应为nul(#0).代码如下:
procedure TestStringOfChar;
var
a: AnsiString;
ac: AnsiChar;
begin
ac := #1;
a := StringOfChar(ac, 43);
if a <> #1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1#1 then
begin
raise Exception.Create('ANSI StringOfChar Failed!!');
end;
end;
Run Code Online (Sandbox Code Playgroud)
我知道StackOverflow上有很多Delphi程序员.你遇到同样的问题吗?如果是,您如何解决?解决办法是什么?顺便说一句,我已经联系了Delphi的开发人员,但到目前为止他们还没有确认也没有否认这个问题.我正在使用Embarcadero Delphi 10.2版本25.0.26309.314.
更新:
如果您的CPU是在2012年或之后生产的,则在调用StringOfChar之前还要包含以下行以重现该问题:
const
ERMSBBit = 1 shl 9; //$0200
begin
CPUIDTable[7].EBX := CPUIDTable[7].EBX and not ERMSBBit;
Run Code Online (Sandbox Code Playgroud)
至于2017年4月的RAD Studio 10.2工具链问题修补程序 - 尝试过它而没有它 - 它没有帮助.无论Hotfix如何,问题都存在.
(如果是这样的话,我会自己做的.)
我的问题:
为方便起见,我倾向于避免间接/索引寻址模式.
作为替代,我经常使用立即,绝对或寄存器寻址.
代码:
; %esi has the array address. Say we iterate a doubleword (4bytes) array.
; %ecx is the array elements count
(0x98767) myloop:
... ;do whatever with %esi
add $4, %esi
dec %ecx
jnz 0x98767;
Run Code Online (Sandbox Code Playgroud)
在这里,我们有一个序列化的组合(dec和jnz),它可以防止正常的乱序执行(依赖).
有没有办法避免/破坏dep?(我不是装配专家).