Im letzten Teil untersuchen wir, wie Schleifen auf Maschinenebene realisiert weden.
Als Klickprozedur wird nachfolgende Zählschleife programmiert:
|
procedure TfoAnwendung.buRunClick(Sender: TObject); var i, a: integer; begin a := 1; for i := 1 to 10 do a := a + 1; lbAusgabe.Caption := IntToStr(a); end; |
Delphi übersetzt die Prozedur in folgenden Maschinencode:
|
Zunächst fallen einige Besonderheiten auf:
Die Anweisung
Der Schleifenzähler wird auf den Endwert initialisiert und dann erniedrigt. Auch hierbei kommt die effektive Anweisung dec (= decrement) zum Einsatz.
Der Sprung zum Anfang der Schleife erfolgt mit
Hier kommt eine weitere Besonderheit von inc bzw dec
zum Tragen. Diese Anweisungen setzen je nach Ergebnis unter anderem das Zero-Flag (ZF) und das Parity-Flag (PF). Beim Einzelschrittmodus lässt sich das auch gut verfolgen. Delphi stellt im CPU-Fenster Veränderungen, die bei einer Anweisung auftreten, rot dar.
So kann tatsächlich der nötige Rücksprung ermittelt werden ohne eine weitere Compare-Anweisung. Jetzt wird auch klar, warum die Schleife rückwärts gezählt wird, da die Auswertung sonst nicht auf diese Weise erfolgen könnte.
Als nächstes betrachten wir die Repeat-Schleife:
|
procedure TfoAnwendung.buRunClick(Sender: TObject); var a, b: integer; begin a := 11; b := 2; repeat a := a - b; until a < b; lbAusgabe.Caption := IntToStr(a); end; |
Der Maschinencode, den Delphi hierzu erzeugt, sieht folgendermaßen aus:
|
Zunächst wird der Schleifenkörper ausgeführt (sub-Anweisung).
Danach erfolgt ein compare von
Als letztes betrachten wir die While-Schleife:
|
procedure TfoAnwendung.buRunClick(Sender: TObject); var a, b: integer; begin a := 11; b := 2; while a >= b; do a := a - b; lbAusgabe.Caption := IntToStr(a); end; |
Der Maschinencode, den Delphi hierzu erzeugt, sieht folgendermaßen aus:
|
Die Abfrage
Man sollte nun annehmen, dass am Ende des Schleifenkörpers ein unbedingter Rücksprung zur Ausführungsbedingung erfolgt. Die Lösung sieht hier anders aus.
Nach einem nochmaligen Compare-Vergleich erfolgt dieses Mal der Sprung im entgegengesetzten Fall wie bei der Ausführungsbedingung: jle wird also ausgeführt, wenn der Schleifenkörper wiederholt werden muss. Es wird um 6 Byte nach vorne übersprungen, was zum Beginn des Schleifenkörpers führt (sub-Anweisung).
Damit ist der zweite Teil der Schleife eigentlich eine Schleife mit Wiederholbedingung am Schluss. Dies entspricht aber der Repeat-Schleife.
Die While-Schleife wird also als Repeat-Schleife mit zusätzlicher Eintrittsbedingung realisiert.
Die nachfolgenden Diagramme zeigen den Ablauf im Vergleich:
[Index] [Einführung] [Logische Schaltelemente - CPU]
Autor: Jürgen Dehmer
Letzte Änderung: 29.02.2004