Delphi 为什么德尔福会这样做?
Delphi XE2,简单代码:Delphi 为什么德尔福会这样做?,delphi,Delphi,Delphi XE2,简单代码: function FastSwap(Value: uint16): uint16; register; overload; asm bswap eax shr eax, 16 end; ... type PPicEleHdr = ^TPicEleHdr; TPicEleHdr = packed record zero, size, count: word; end; var count: integer; buf: TByt
function FastSwap(Value: uint16): uint16; register; overload;
asm
bswap eax
shr eax, 16
end;
...
type
PPicEleHdr = ^TPicEleHdr;
TPicEleHdr = packed record
zero, size, count: word;
end;
var
count: integer;
buf: TBytes;
begin
...
peh := @buf[offs];
count := integer(FastSwap(peh.count));
for i := 0 to count - 1 do begin
这是我在CPU窗口中看到的
UnitExtract.pas.279: for i := 0 to count - 1 do begin
0051E459 8B45DC mov eax,[ebp-$24]
0051E45C 48 dec eax
0051E45D 85C0 test eax,eax
0051E45F 0F82CD000000 jb $0051e532
0051E465 40 inc eax
0051E466 8945AC mov [ebp-$54],eax
0051E469 C745F400000000 mov [ebp-$0c],$00000000
因此,当计数为0时,任何东西都不能正常工作,测试eax,eax eax=$FFFFFFFF dec eax后不影响进位标志,而jb通过进位标志进行操作。
有什么我不明白的吗?通过逆向工程的过程,我推断我是一个无符号32位整数,基数。因此编译器在无符号上下文中执行for循环算法。这意味着Count-1被解释为无符号,因此循环从0运行到highi 为了充实这一点,这是一步一步发生的: 计数为00000000美元。 计算计数-1,其值为$FFFFFFFF。 解释为无符号整数$FFFFFF为232-1。
通过反向工程过程,您的循环体对所有值0执行,我推断I是一个无符号32位整数,基数。因此编译器在无符号上下文中执行for循环算法。这意味着Count-1被解释为无符号,因此循环从0运行到highi 为了充实这一点,这是一步一步发生的: 计数为00000000美元。 计算计数-1,其值为$FFFFFFFF。 解释为无符号整数$FFFFFF为232-1。
您的循环体对写入的所有值0执行,这不会编译,因为您没有i的声明 但是我的心理调试感觉说我在某处被声明为基数无符号整数,因此当它尝试计算0-1时,它得到的是MAXINT而不是-1,因为无符号整数不能表示负值
如果无符号整数有可能变为负数,则绝对不要将其用作for循环的索引变量或边界变量。否则,就会出现这样的错误。事实上,您一般不应该使用无符号整数。它们没有看上去那么有用如果你需要一个大于某个大小的最大有符号值的值,很可能你最终需要一个大于该值两倍的值,所以你真正需要的是下一个更大的整数大小,它们往往会导致像这样的奇怪错误。如前所述,这不会编译,因为你没有我的申报单 但是我的心理调试感觉说我在某处被声明为基数无符号整数,因此当它尝试计算0-1时,它得到的是MAXINT而不是-1,因为无符号整数不能表示负值
如果无符号整数有可能变为负数,则绝对不要将其用作for循环的索引变量或边界变量。否则,就会出现这样的错误。事实上,您一般不应该使用无符号整数。它们没有看上去那么有用如果你需要一个大于某个大小的最大有符号值的值,很可能你最终需要一个大于该值两倍的值,因此,您真正需要的是下一个更大的整数大小,它们往往会导致像这样的奇怪错误。FWIW如果您提供了完整的代码,这个问题会更容易回答。在本例中,Mason和我能够从asm推断您的整数是无符号的。不过,最好提供一个尽可能短的完整程序。整个源代码相当大:从文件夹中提取tiff文件中的奖金数据,但下面的答案很有用。是的,当然整个源代码很大。这就是为什么要将其缩减为一个完整的可编译的10行示例。这就是你需要证明这个问题的全部内容。这样做总是值得的。顺便说一下,使用xchg al,ah-1,16位操作数的字节转换可以更容易、更快地完成。你问为什么循环会这样,然后说什么都不起作用。你需要更具体一些。描述循环是如何工作的。说明程序正常运行意味着什么。你问是否有什么你不明白的;可能有,但是你需要陈述你的理解是什么,然后其他人才能确定你遗漏了什么。FWIW如果你提供了完整的代码,这个问题会更容易回答。在本例中,Mason和我能够从asm推断您的整数是无符号的。不过,最好提供一个尽可能短的完整程序。整个源代码相当大:从文件夹中提取tiff文件中的奖金数据,但下面的答案很有用。是的,当然整个源代码很大。这就是为什么要将其缩减为一个完整的可编译的10行示例。这就是你需要证明这个问题的全部内容。这样做总是值得的。顺便说一下,使用xchg al,ah-1,16位操作数的字节转换可以更容易、更快地完成。你问为什么循环会这样,然后说什么都不起作用。你需要更具体一些。描述循环是如何工作的。说明程序正常运行意味着什么。你问是否有什么你不明白的;可能有,但你需要说明你的理解是什么
在任何人都能确定你遗漏了什么之前。同样谢谢,不幸的是我不能将两条消息标记为答案。但你不必选择梅森的!!;-这绝对是一个玩笑!!!!好的:你的答案更进一步:我想编译器是根据计数类型来决定的,我以前遇到过这样的问题:编译器忽略了v:=bytesomeint;所以不要对i类型给予足够的关注。是的,重要的是循环变量的类型。我记得在将代码库从Modula-2(使用基于1的索引)移植到Delphi 1(使用基于0的索引)时,我以一种艰难的方式学习了这一点。这并不漂亮,我一次又一次地碰到你的问题。我当时学习很慢,所以根本不存在!!另外谢谢,很遗憾,我无法将两条消息标记为答案。但您不必选择梅森的!!;-这绝对是一个玩笑!!!!好的:你的答案更进一步:我想编译器是根据计数类型来决定的,我以前遇到过这样的问题:编译器忽略了v:=bytesomeint;所以不要对i类型给予足够的关注。是的,重要的是循环变量的类型。我记得在将代码库从Modula-2(使用基于1的索引)移植到Delphi 1(使用基于0的索引)时,我以一种艰难的方式学习了这一点。这并不漂亮,我一次又一次地碰到你的问题。我当时学习很慢,所以根本不存在!!