帕斯卡倒计数而不是向上?太奇怪了

时间:2018-05-27 20:07:32

标签: delphi delphi-7

http://rextester.com/OXRFB95557

手表显示计数器j没有下降......任何想法为什么?感谢

http://localhost/page?id=contact

2 个答案:

答案 0 :(得分:6)

您在Delphi 7中对j: integerprocedure 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)

您的诊断不正确。索引变量在该循环中计数。

如果未使用循环变量,编译器可能会优化循环计数器以在其选择的顺序中运行。但是在你的循环中使用索引变量,所以它必须增加。