答案 0 :(得分:6)
您在Delphi 7中对j: integer
中procedure PrintCards()
变量的观察与调试器监视中显示的完全相同。但是,请放心,for
循环正常工作。
在你的代码中,你给了j
两个职责,1)充当循环控制,2)充当shuffledCards[]
数组的索引。
编译器将您的delphi代码转换为有效(但当然是正确的)机器代码。因此,将ZF
(零标志)作为循环终止条件进行检测,而不是与const值进行显式比较,这是提高效率的一种方法。因此,通过在这种情况下使用递减循环控制寄存器esi
来解决占空比1)(参见下面的反汇编)。
对于第二个任务,esi
寄存器不能使用,因为它指向错误的方向。因此,另一个寄存器ebx
用于职责2)。它被设置为指向数组的第一个元素的指针(索引为1的元素)。然后在循环中的每一轮ebx
递增以指向下一个元素。
这是PrintCards()
程序的反汇编:
Project2.dpr.38: begin
0040876C 53 push ebx
0040876D 56 push esi
0040876E 57 push edi
0040876F 8BF8 mov edi,eax
Project2.dpr.39: for j := 1 to 21 do
00408771 BE15000000 mov esi,$00000015 // Initialize loop control
00408776 8BDF mov ebx,edi // set up pointer to array
Project2.dpr.40: writeln(shuffledCards[j]);
00408778 A160934000 mov eax,[$00409360] // loop start
0040877D 8B13 mov edx,[ebx]
0040877F E8B4B8FFFF call @WriteOLString
00408784 E8CFA5FFFF call @WriteLn
00408789 E8B69EFFFF call @_IOTest
0040878E 83C304 add ebx,$04 // advance array element pointer
Project2.dpr.39: for j := 1 to 21 do
00408791 4E dec esi // decrement loop control
00408792 75E4 jnz -$1c // jump if not zero to loop start
Project2.dpr.41: end;
00408794 5F pop edi
00408795 5E pop esi
00408796 5B pop ebx
00408797 C3 ret
在第39行放置一个断点,然后运行。在第39行停止时,调用CPU视图(查看 - 调试Windows - CPU或Ctrl-Alt-C)。然后单步(F8)并按照寄存器的变化,自己查看
j
的调试器监视显示esi
的值,因此您会看到值从21减少到1(实际上您可以看到最后一次显示在最后一次{{ 1}}被执行)。
答案 1 :(得分:2)
您的诊断不正确。索引变量在该循环中计数。
如果未使用循环变量,编译器可能会优化循环计数器以在其选择的顺序中运行。但是在你的循环中使用索引变量,所以它必须增加。