Ваше наблюдение в Delphi 7 относительно переменной j: integer
в procedure PrintCards()
точно так же, как это показано в часах отладчика.Однако, будьте уверены, цикл for
работает правильно.
В вашем коде вы дали j
две обязанности: 1) действовать как элемент управления цикла и 2) действовать как индекс дляshuffledCards[]
array.
Компилятор преобразует ваш Delphi-код в максимально эффективный (но, конечно, правильный) машинный код.Организация цикла таким образом, что обнаружение ZF
(нулевой флаг) в качестве условия завершения цикла вместо явного сравнения со значением const является одним из способов повышения эффективности.Следовательно, обязанность 1) решается с помощью управления с уменьшающимся контуром, в этом случае зарегистрируйте esi
(см. Разборку ниже).
Для второй обязанности регистр 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 (View - Debug Windows - CPU или Ctrl-Alt-C).Затем выполните один шаг (F8) и проследите за изменениями регистров, чтобы увидеть для себя
Часы отладчика для j
показывают значение esi
, поэтому вы видите, что значение снижается с 21 до 1(на самом деле вы можете видеть, что финальный 0 появляется сразу после последнего выполнения dec esi
).