数组 – Delphi XE字节数组索引
我像这样使用简单的循环缓冲区
var Values: array [byte] of single; ptr: byte; 在这个测试例子中 for ptr:=0 to 10 do Values[Byte(ptr-5)]:=1; 我希望设置为1前5个值和最后5个值,但XE4 compiller产生不正确的代码,它使用32位指针数学来计算数组索引: for ptr:=0 to 10 do Values[Byte(ptr-5)]:=1; 005B94BB C645FB00 mov byte ptr [ebp-$05],$00 005B94BF 33C0 xor eax,eax 005B94C1 8A45FB mov al,[ebp-$05] 005B94C4 C78485E0FBFFFF0000803F mov [ebp+eax*4-$0420],$3f800000 005B94CF FE45FB inc byte ptr [ebp-$05] 005B94D2 807DFB0B cmp byte ptr [ebp-$05],$0b 005B94D6 75E7 jnz $005b94bf 这是我的错误代码和操作字节索引的正确方法吗? 解决方法
问题是:
让我们将反汇编与溢出检查打开/关闭进行比较. {$Q+} Project71.dpr.21: for ptr:= 0 to 10 do Values[Byte(ptr-5)]:= 1; 0041D568 33DB xor ebx,ebx 0041D56A 0FB6C3 movzx eax,bl 0041D56D 83E805 sub eax,$05 0041D570 7105 jno $0041d577 0041D572 E82D8DFEFF call @IntOver 0041D577 0FB6C0 movzx eax,al 0041D57A C704870000803F mov [edi+eax*4],$3f800000 0041D581 43 inc ebx 0041D582 80FB0B cmp bl,$0b 0041D585 75E3 jnz $0041d56a {$Q-} Project71.dpr.21: for ptr:= 0 to 10 do Values[Byte(ptr-5)]:= 1; 0041D566 B30B mov bl,$0b 0041D568 B808584200 mov eax,$00425808 0041D56D C7000000803F mov [eax],$3f800000 0041D573 83C004 add eax,$04 0041D576 FECB dec bl 0041D578 75F3 jnz $0041d56d 使用{$Q}包装有效,而使用{$Q-}包装不起作用,并且当设置{$R}时,编译器不会为错误的数组索引生成范围错误. 因此,对我来说结论是:由于范围检查不会为数组索引超出边界生成运行时错误,因此需要进行换行. 这一事实进一步证明了在启用溢出检查时完成换行的事实. 这应该报告为编译器中的错误. 完成:https://quality.embarcadero.com/browse/RSP-15527“类型转换在数组索引中失败” 注意:@Rudy在他的回答中提供了一种解决方法. 附录: 以下代码: for ptr:= 0 to 10 do WriteLn(Byte(ptr-5)); 产生: 251 252 253 254 255 0 1 2 3 4 5 对于范围/溢出检查的所有组合. 同样值[Byte(-1)]:= 1;为所有编译器选项的值[255]分配1. Value Typecasts的文档说:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |