Step 7 Indirekte Adressierung mit AWL

Zuviel Werbung?
-> Hier kostenlos registrieren
TAK Tauscht Akku 1 gegen Akku 2 und Akku 2 gegen Akku 1

ich habe nochmal über die rekursive Lösung nachgedacht ... lineare Rekursion wäre nach meinem Dafürhalten in der folgenden Lösung realisiert.

Code:
*
      LAR1  P#0.0
        
      AUF   DB     3
      L     DBLG
      SRW   1
next: T     MW    10
      INVI  
      +     1001
      T     DBW [AR1,P#0.0]
      +AR1  P#2.0
      L     MW    10
      LOOP  next

Was es mit einem "rekursiven Impuls" auf sich hat, konnte sich mir bisher nicht erschließen.
 
Zuletzt bearbeitet:
Hallo Joe,

mit "T MW 30" schreibst Du Deinen neuen Wert ins MW 30 (Ergebnis der vorherigen Berechnung. Steht im Akku 1)
Mit "L 2000" wird das Ergebnis der Berechnung vom Akku 1 in den Akku 2 geschoben und die 2000 in den Akku 1 geschrieben.
dann erfolgt der Vergleich.
Mit TAK (Tausche Akku) wir das Ergebnis der Berechnung vom Akku 2 in den Akku 1 geschrieben und die 2000 vom Akku 1 in den Akku 2.
Somit hast Du das Ergebnis der Berechnung (MW 30) vor Deinem Sprung zu "hier" wieder im Akku 1 stehen.
Das brauchst Du, weil nach der Sprungmarke "hier" ja der Akku 1 in Deinen DB geschrieben wird (T DBW [MD10]).

Ich hoffe ich habs einigermaßen verständlich geschrieben.

Grüße
Gebs
 
Hallo Joe,

mit "T MW 30" schreibst Du Deinen neuen Wert ins MW 30 (Ergebnis der vorherigen Berechnung. Steht im Akku 1)
Mit "L 2000" wird das Ergebnis der Berechnung vom Akku 1 in den Akku 2 geschoben und die 2000 in den Akku 1 geschrieben.
dann erfolgt der Vergleich.
Mit TAK (Tausche Akku) wir das Ergebnis der Berechnung vom Akku 2 in den Akku 1 geschrieben und die 2000 vom Akku 1 in den Akku 2.
Somit hast Du das Ergebnis der Berechnung (MW 30) vor Deinem Sprung zu "hier" wieder im Akku 1 stehen.
Das brauchst Du, weil nach der Sprungmarke "hier" ja der Akku 1 in Deinen DB geschrieben wird (T DBW [MD10]).

Ich hoffe ich habs einigermaßen verständlich geschrieben.

Grüße
Gebs

Ich danke dir. Deine Rede ist nachvollziehbar. Aber was ich nicht verstanden habe, ist quasi wenn MW30 überprüft wird und ist kleiner als 2000 was passiert? wo springt er hin? und wenn nicht kleiner (Also größer oder gleich), was passiert? welcher Schritt wird bei jedem Fall durchgeführt? und wozu ist das Nützlich, wenn Akku1 und Akku2 mit einander getauscht werden?
Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Joe,

das TAK ist nützlich, wenn Du Berechnung gemacht hast, und dann, wie bei Dir diesen berechneten Wert
mit einer Konstanten vergleichen willst. Wenn Du jetzt mit Deinem berechneten Wert weiterarbeiten willst,
musst Du ihn ja irgendwie zurück in den Akku 1 bekommen.
Code:
L 5          // jetzt steht 5 im Akku 1
L 4          // jetzt steht die 5 in Akku 2 und im Akku 1 steht 4
*I           // Jetzt steht 20 im Akku 1 (Ergebnis der Multiplikation) und 5 im Akku 2
L 21        // jetzt steht 21 im Akku 1 und 20 im Akku 2
==I        // Vergleich
             // Irgendeine Aktion
             // Wenn Du jetzt mit der 20 weiterrechnen willst, musst Du sie wieder in den Akku 1 bekommen =>
TAK       // jetzt ist die 20 wieder im Akku 1
Wenn Das MW 30 kleiner ist als 2000 springt das Programm zur Sprungmarke "hier"
Wenn das MW 30 größer, oder gleich ist, dann ist die Bedingung für das SPB ja nicht
erfüllt. Deshalb macht das Programm hinter dem SPB hier weiter.
(SPB heisst: Springe zur Sprungmarke, wenn die Bedingung davor wahr ist, sonst mach
in der nächsten Zeile weiter.)

Grüße
Gebs
 
ich habe nochmal über die rekursive Lösung nachgedacht ... lineare Rekursion wäre nach meinem Dafürhalten in der folgenden Lösung realisiert.

Code:
*
      LAR1  P#0.0
        
      AUF   DB     3
      L     DBLG
      SRW   1
next: T     MW    10
      INVI  
      +     1001
      T     DBW [AR1,P#0.0]
      +AR1  P#2.0
      L     MW    10
      LOOP  next
Hmm, ich sehe da keine Rekursion? für mich ist das eindeutig iterativ.

PS: ich würde noch ein SLW 1 spendieren

Harald
 
wozu SLW 1?

wenn das iterativ ist, so sollte es per Definition mgl. sein es rekursiv darzustellen. (warum auch immer man das tun sollte)

woher stammt die Aufgabenstellung und vielleicht könnte der Aufgabensteller dazu etwas sagen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Inhalt soll gleich der Datenwortnummer sein z.B. DB100.DW0=0, DB100.DW2=2 usw.



Die Aufgabe soll in AWL gelöst werden mit Hilfe eines rekursiven Impuls.
woher stammt die Aufgabenstellung und vielleicht könnte der Aufgabensteller dazu etwas sagen.
Das meine ich auch. Die Frage, was mit "rekursiver Impuls" gemeint ist, ist von Anfang an ungeklärt.
Wer weiß, ob da tatsächlich das Wort "rekursiv" in der Aufgabenstellung steht? Vielleicht ist einfach ein stinknormaler Triggerpuls (rising edge) gemeint, damit das Beschreiben des DB nur einmal ausgeführt wird???

Harald
 
Das meine ich auch. Die Frage, was mit "rekursiver Impuls" gemeint ist, ist von Anfang an ungeklärt.
Wer weiß, ob da tatsächlich das Wort "rekursiv" in der Aufgabenstellung steht? Vielleicht ist einfach ein stinknormaler Triggerpuls (rising edge) gemeint, damit das Beschreiben des DB nur einmal ausgeführt wird???

Harald

Hallo Harald,
Alles ist in Ordnung, dieser rekursive Impuls muss nicht sein. Danke
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Diese Schritte habe nicht verstanden:
T MW 30
L 2000
<I
TAK //MW30 zurück in AKKU1
SPB hier

Was macht TAK und was wolltest du damit sagen?
Wie Gebs schon in #24 schrieb:
Wenn der Sprung zu "hier" ausgeführt wird, dann muß der Wert von MW30 im AKKU1 stehen, weil der Wert da in den DB geschrieben wird. Wegen dem "L 2000" für den Vergleich steht aber die 2000 in AKKU1 und der Wert von MW30 wurde in AKKU2 geschoben. Wie bekommt man nun am einfachsten den Wert zurück in AKKU1? --> entweder mit TAK (tauscht die Inhalte von AKKU1 und AKKU2) oder mit POP (holt den Inhalt von AKKU2 in AKKU1) oder durch erneutes Laden aus dem MW30. Erneutes Laden wäre schön übersichtlich, TAK und POP sind aber kürzer und schneller als das Laden, POP ist für viele AWL-Leser nicht so geläufig, also habe ich mich für TAK entschieden. Man kann das Programm aber auch anders schreiben, z.B. das "L MW30" direkt in der Zeile hinter "hier:" machen, oder den Vergleich mit 2000 andersrum formulieren, so daß die 2000 in AKKU2 steht und der neue Wert des MW30 in AKKU1 steht, oder ...

Harald
 
Wie Gebs schon in #24 schrieb:
Wenn der Sprung zu "hier" ausgeführt wird, dann muß der Wert von MW30 im AKKU1 stehen, weil der Wert da in den DB geschrieben wird. Wegen dem "L 2000" für den Vergleich steht aber die 2000 in AKKU1 und der Wert von MW30 wurde in AKKU2 geschoben. Wie bekommt man nun am einfachsten den Wert zurück in AKKU1? --> entweder mit TAK (tauscht die Inhalte von AKKU1 und AKKU2) oder mit POP (holt den Inhalt von AKKU2 in AKKU1) oder durch erneutes Laden aus dem MW30. Erneutes Laden wäre schön übersichtlich, TAK und POP sind aber kürzer und schneller als das Laden, POP ist für viele AWL-Leser nicht so geläufig, also habe ich mich für TAK entschieden. Man kann das Programm aber auch anders schreiben, z.B. das "L MW30" direkt in der Zeile hinter "hier:" machen, oder den Vergleich mit 2000 andersrum formulieren, so daß die 2000 in AKKU2 steht und der neue Wert des MW30 in AKKU1 steht, oder ...

Harald

Hi,
ich habe es verstanden, aber wie die Schleife verlassen wird (beendet) habe nicht kappiert, weil wenn die Schleife nicht verlassen wird, stürzt er ab(weil er einen unendlichen Zyklus hat).
Gruß
 
Zuviel Werbung?
-> Hier kostenlos registrieren
wie die Schleife verlassen wird (beendet) habe nicht kappiert, weil wenn die Schleife nicht verlassen wird, stürzt er ab(weil er einen unendlichen Zyklus hat).
Da stürzt nichts ab. LOOP oder SPB springen bedingt nur dann zurück zum Schleifenanfang, solange die Schleife noch nicht 1000-mal ausgeführt wurde. Nach vollständiger Abarbeitung der Schleife ist die Rücksprungbedingung nicht mehr erfüllt und der Sprung deshalb nicht mehr ausgeführt und das Programm wird einfach mit der nächsten Anweisung nach der Schleife fortgesetzt.

Harald
 
Da stürzt nichts ab. LOOP oder SPB springen bedingt nur dann zurück zum Schleifenanfang, solange die Schleife noch nicht 1000-mal ausgeführt wurde. Nach vollständiger Abarbeitung der Schleife ist die Rücksprungbedingung nicht mehr erfüllt und der Sprung deshalb nicht mehr ausgeführt und das Programm wird einfach mit der nächsten Anweisung nach der Schleife fortgesetzt.

Harald

Hezlichen Dank. Jetzt habe ich nachvollzogen. Mein Fehler am Anfang war, dass ich den Sprung anders bedingt habe (Wenn MW30>2000 dann spring zum anfang wieder mit SPA Anf) und so verlässt er nie die Schleife. Aber mit deiner Methode führt er die Befehle aus bis Mw30 die 2000 erreicht danach springt er automatisch raus (wenn ich das richtig verstanden habe).
 
Zuletzt bearbeitet:
Ja, hast Du richtig verstanden. :)

Man kann das Programm noch in ...zig weiteren Varianten schreiben, z.B. eine wo erst der Schleifenzähler geprüft wird und dann die Schleife ausgeführt wird.

Variante "Speicherindirekt" mit dem Pointer in einem DWORD in TEMP
Code:
// Schleife initialisieren
      L     0
      T     MW    10                    //Schleifenzähler (Index)

      AUF   DB    100                   //Global Datenbaustein DB100 mit 1000 INT

// Schleife schon komplett abgearbeitet?
next:  L     1000
      L     MW    10
      <=I   
      SPB   ende                        //ja, fertig

// nein: 0, 2, 4 ... 1998 in DB100.DBW[0, 2, 4 ... 1998] schreiben
// DB100.DBW[Index*2] := Index*2 ;
      SLD   4                           //Index * 16 --> DBW_Adresse P#xxxx.0
      T     #tmp_DW_Adr
      SRD   3                           //Index * 2  --> Wert, der in DBW geschrieben wird
      T     DBW [#tmp_DW_Adr]

// Schleifenzähler weiterschalten
      L     MW    10
      +     1
      T     MW    10
      SPA   next                        //nächstes DBW

// Fertig
ende:  NOP   0

Variante "Registerindirekt" mit dem Pointer in AR1
Code:
// Schleife initialisieren
      L     0
      T     MW    10                    //Schleifenzähler (Index)

      AUF   DB    100                   //Global Datenbaustein DB100 mit 1000 INT

// Schleife schon komplett abgearbeitet?
next: L     1000
      L     MW    10
      <=I   
      SPB   ende                        //ja, fertig

// nein: 0, 2, 4 ... 1998 in DB100.DBW[0, 2, 4 ... 1998] schreiben
// DB100.DBW[Index*2] := Index*2 ;
      SLD   4                           //Index * 16 --> DBW_Adresse P#xxxx.0
      LAR1  
      SRD   3                           //Index * 2  --> Wert, der in DBW geschrieben wird
      T     DBW [AR1,P#0.0]

// Schleifenzähler weiterschalten
      L     MW    10
      +     1
      T     MW    10
      SPA   next                        //nächstes DBW

// Fertig
ende: NOP   0

Harald
 
Zurück
Oben