Dekrementacja zamiast inkrementacji

0

Witam.

Zauważyłem w Delphi 5 dziwną/ciekawą dla mnie rzecz (nie wiem jak to się ma do innych wersji).
Zilustruję to przykładem:

procedure Hello;
var i:integer;
begin
for i:=1 to 10 do
	beep;
end;

Niby nic niezwykłego, zwykła pętla for. Jeżeli natomiast przyjrzymy się jej za pomocą debuggera to zauważymy, że zmienna i tak naprawdę jest dekrementowana od 10 do 1. Co prawda nie wpływa to w żaden sposób na działanie programu, jednak bardzo mnie ciekawi dlaczego tak się dzieje? Jakie są ku temu powody, bo chyba muszą być jakieś?

0
for i := 1 to 3 do showmessage(inttostr(i));
for i := 3 downto 1 do showmessage(inttostr(i));

eee?

0

Wiadomo, że jak używasz zmiennej i wewnątrz pętli to musi ona być inkrementowana. Inaczej 100% programów przestałaby działać. Spróbuj nie używać zmiennej sterującej i sprawdzić jej zawartość w debuggerze.

0

hmm rzeczywiscie :O

powiem wiecej - przy downto odlicza sie od -3 do -1 :D

EDIT: po wylaczeniu optymalizacji (Project->Options...->Compiler->Code generation->Optimization) sie liczy normalnie - widocznie tak szybciej :]

0

Rzeczywiście. Teraz moje pytanie brzmi następująco:
Dlaczego bardziej optymalnie jest liczyć od 10 do 1, niż od 1 do 10?

0

przy liczeniu 1 -> 10, warunkiem wyjścia z pętli jest i > 10, w asmie:

; jeśli to był ostatni przebieg, ecx = 10
inc ecx
; ecx = 11
cmp ecx, 10
; 11 > 10
jg koniec_petli

Kiedy warunkiem końca petli jest i = 1, sprawa się dramatycznie upraszcza:

; jeśli to był ostatni przebieg, ecx = 1
dec ecx
; czyli teraz ecx = 0, wiec flaga ZF = 1
jz koniec_petli

Po prostu uszczędzamy na każdym przebiegu pętli chyba ze 2-3 takty procesora :P.

//Na przyszłość: Debug -> CPU Window, albo jakoś tak... Tam jest podgląd bieżącego kodu w ASMie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1