Step 7 Bestimmten DB Bereich mit Pointer prüfen ob alles auf Null ist.

tommylik

Well-known member
Beiträge
80
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo,

Möchte in einem DB ab Offset (int) der als Input übergeben wird
10 Doppelwörter prüfen ob sie gelöscht wurden.

Folgender Code funktioniert leider nicht so wie ich möchte.

Der Ausgang #Vergleich_Erfolgreich ist immer gesetzt egal ob der DB Bereich gelöscht ist oder nicht.

Und wie kann ich sicher sein das auch wirklich jedes Doppelwort überprüft worden ist.

Code:
      U     E     30.0
      FP    M     30.0

      SPBN  end

      L     #iStartAdr                    // Beginn DB Bereich Input (int)
      
      L     P#DBX 0.0                  //Adresse des ersten DWord
      T     #dwPointer                 //(DWORD in TEMP)
      AUF   #DB_Nr                    //Input Block_DB

      L     10
Su:   T     MW   300

      L     DBW [#dwPointer]
      L     0                              // Wenn alles 0 dann ausprung.
      ==I   
      SPB   out

      L     #dwPointer
      L     P#40.0                      //Länge der Struktur ist 40 Byte / 10 DWord
      +D                                   
      T     #dwPointer                //Pointer auf nächstes DWord weiterstellen

      L     MW   300
      LOOP  Su

      CLR   
      =     #Vergleich_Erfolgreich

      SPA   end
out:  SET   
      =     #Vergleich_Erfolgreich

end:  NOP   0

Kann mir einer von Euch bitte sagen was am Code falsch ist.

Mfg Tommylik
 

Ralle

Supermoderator
Teammitglied
Beiträge
14.246
Punkte Reaktionen
3.296
Code:
      U     E     30.0
      FP    M     30.0

      SPBN  end

       S[COLOR=#ff0000]     #Vergleich_Erfolgreich[/COLOR]

      L     #iStartAdr                    // Beginn DB Bereich Input (int)
      
      L     [COLOR=#ff0000]P#0.0 [/COLOR]                 //Adresse des ersten DWord --> 0.0 Pointerformat
      T     #dwPointer                 //(DWORD in TEMP)
      AUF   #DB_Nr                    //Input Block_DB

      L     10
Su:   T     MW   300

      L     [COLOR=#ff0000]DBD[/COLOR] [#dwPointer]
      L     0                              // Wenn alles 0 dann ausprung.
      [COLOR=#ff0000]<>I [/COLOR]       
      SPB   out

      L     #dwPointer
      [COLOR=#ff0000]L     P#4.0 [/COLOR]                     //das nächste [COLOR=#ff0000]DWord[/COLOR] liegt 4 Byte im Pointerformat weiter
      +D                                   
      T     #dwPointer                //Pointer auf nächstes DWord weiterstellen

      L     MW   300
      LOOP  Su

[COLOR=#ff0000]      SPA end

out:  SET   
       R    #Vergleich_Erfolgreich
end: NOP 0[/COLOR]

Ich hab mal rot die Änderungen eingetragen.

Nochmal korrigiert!

PS. Du kannst MW300 auch einfach durch eine Temp ersetzen.

OK, nochmal korrigiert
Du willst DBD als auch immer DBD und 4 Byte addieren.
 
Zuletzt bearbeitet:

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
16.865
Punkte Reaktionen
4.949
Code:
      L     #iStartAdr                  // Beginn DB Bereich Input (int)
      SLD   3                           // StartAdr ---> P#StartAdr.0
      T     #dwPointer

      AUF   #DB_Nr                      // Input Block_DB

      L     10
Su:   T     #iSchleifenzaehler

      L     DBD [#dwPointer]
      L     0
      <>D   
      SPB   out                         // Abbrechen sobald <> 0 gefunden

      L     #dwPointer
      L     P#4.0                       // Pointer auf nächstes DWord weiterstellen
      +D    
      T     #dwPointer

      L     #iSchleifenzaehler
      LOOP  Su

      CLR                               // wenn hier aus Schleife, dann waren alle DBD = 0   
out:  NOT   
      =     #Vergleich_Erfolgreich      // 1 = alle 10 DBD sind 0

Harald
 
OP
T

tommylik

Well-known member
Beiträge
80
Punkte Reaktionen
0
Zuviel Werbung?
->Hier kostenlos registrieren
Hallo Ralle,

Vielen Dank für deine Antwort und Mühe.

Wenn ich dein Code übernehme dann ist der Ausgang immer 0.
Egal ob ich etwas in den DB Bereich etwas rein schreibe oder nicht.

Ich habe das Rücksetzen und Setzen mal vertauscht dann ist der Ausgang immer 1.
Egal ob ich etwas in den DB Bereich etwas rein schreibe oder nicht.

Ich möchte das der Ausgang 1 ist wenn der Bereich gelöscht ist.
Das wäre für mich so als wenn ich den DB initialisiere dann ist ja auch alles auf 0.

Ich denke die Beschriftung vom Ausgang ist nicht gut gewählt.
Ich habe den Ausgang umbenannt auf #Bereich_leer.

Ich werde weiter probieren.

Vielleicht hast du noch eine Idee woran das liegt.

Vielen Dank nochmal für deine Hilfe.

Mfg Tommylik
 
OP
T

tommylik

Well-known member
Beiträge
80
Punkte Reaktionen
0
Hallo,

Upps da war ich zu langsam mit dem Schreiben.

Vielen Dank Harald. So funktioniert es.

Vielen Dank auch an alle anderen für die Hilfe.

Mfg Tommylik
 

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
16.865
Punkte Reaktionen
4.949
Problem in Deinem und dem von Ralle korrigierten Code: es werden immer die ersten 40 Byte des DB überprüft, egal welche Anfangsadresse in iStartAdr vorgegeben wird.
Hast Du mal meinen Code #5 ausprobiert?

PS: jetzt war ich zu langsam mit tippseln ;)

Harald
 

Ralle

Supermoderator
Teammitglied
Beiträge
14.246
Punkte Reaktionen
3.296
Zuviel Werbung?
->Hier kostenlos registrieren
Problem in Deinem und dem von Ralle korrigierten Code: es werden immer die ersten 40 Byte des DB überprüft, egal welche Anfangsadresse in iStartAdr vorgegeben wird.
Hast Du mal meinen Code #5 ausprobiert?

PS: jetzt war ich zu langsam mit tippseln ;)

Harald

Ja, dass mit seiner Startadresse nichts passiert war mir irgendwie zu Beginn kurz aufgefallen, über die Korrektur des Codes war mit das dann durch die Lappen gegangen.
Gemensam bringen wir das doch immer hin. :icon_mrgreen:
 
OP
T

tommylik

Well-known member
Beiträge
80
Punkte Reaktionen
0
Hallo Harald,

Der obige Code zeigt mir ob alles leer ist. Ok funktioniert


Viel interessanter wäre für mich zu wissen, über eine temp Variable die Adresse angezeigt zu bekommen welches das nächste leere Doppelwort ist.
Und wenn alle Doppelwörter belegt sind soll der Ausgang Bereich_belegt gesetzt werden.

Code:
 L     #iStartAdr                  // Beginn DB Bereich Input (int)
      SLD   3                           // StartAdr ---> P#StartAdr.0
      T     #dwPointer

      AUF   #DB_Nr                      // Input Block_DB

      L     10
Su:   T     #iSchleifenzaehler

      L     DBD [#dwPointer]
      L     1
      ==D   ???
      SPB   out                         // Abbrechen sobald eine 1 gefunden

      L     #dwPointer
      L     P#4.0                       // Pointer auf nächstes DWord weiterstellen
      +D    
      T     #dwPointer                   
      T     #freies_DW                  //  

      L     #iSchleifenzaehler
      LOOP  Su

                                       
out:  ???
        =     #Bereich_belegt             // 1 = alle 10 DBD sind belegt



Könntest du mir bitte helfen?

Mfg Tommylik
 

Ralle

Supermoderator
Teammitglied
Beiträge
14.246
Punkte Reaktionen
3.296
Ich würde auf 0 vergleichen
Wenn = 0, dann wird zu out gesprungen.
Dort wird #Bereich-belegt zurückgesetzt
Schau dir in dem Moment den Schleifenzähler an, er zählt rückwärts, also beinhaltet es den Punkt, an welchem rausgesprungen wurde, aber von 10 an abwärts. Den Schleifenzähler oder (10 - Schleifenzähler) schreibst du in eie statische Variable.
Wenn du durch die Schleife kommst, ohne rauszuspringen, kannst du genau nach dem Aufruf Loop, die Variable #Bereich_belegt auf 1 setzen, denn dann war kein Vergeleich in der Loop auf 0 erfolgreich, also ist alles belegt.
Anschließend aber noch absolut hinter out springen, sonst läuft das Programm auch da durch.
 
Zuletzt bearbeitet:

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
16.865
Punkte Reaktionen
4.949
Zuviel Werbung?
->Hier kostenlos registrieren
Da brauchst Du vom obigen Code einfach nur <>D in ==D ändern, weil jetzt suchst Du ein "leeres" DBD, und die Adresse des gefundenen DBD steht dann in #dwPointer:
Code:
      L     #iStartAdr                  // Beginn DB Bereich Input (int)
      SLD   3                           // StartAdr ---> P#StartAdr.0
      T     #dwPointer

      AUF   #DB_Nr                      // Input Block_DB

      L     10
Su:   T     #iSchleifenzaehler

      L     DBD [#dwPointer]
      L     0
      [COLOR="#0000FF"]==D[/COLOR]
      SPB   out                         // "leeres" DBD gefunden!

      L     #dwPointer
      L     P#4.0                       // Pointer auf nächstes DWord weiterstellen
      +D    
      T     #dwPointer                   

      L     #iSchleifenzaehler
      LOOP  Su

      CLR                               // wenn hier aus Schleife, dann waren alle DBD <> 0
out:  NOT
      =     [COLOR="#0000FF"]#Bereich_belegt             // 1 = alle 10 DBD sind belegt

//Wenn ein leeres DBD gefunden wurde, dann steht dessen Adresse in #dwPointer
      L     #dwPointer
      T     #freies_DW                  // DBD-Adresse als P#Adresse.0

//Falls Du die Adresse nicht als P#1234.0 sondern als Zahl 1234 brauchst:
      SRD   3                           // P#Adresse.0 --> Adresse (Offset)
      T     #Offset_freies_DW[/COLOR]
Harald
 

Ralle

Supermoderator
Teammitglied
Beiträge
14.246
Punkte Reaktionen
3.296
Direkt hinter der Anweisung Loop über den restlichen Code zu einer marke end springen, die ganz am ende des Codes steht.!
 

PN/DP

User des Jahres 2011 - 2013; 2015 - 2017; 2020
Beiträge
16.865
Punkte Reaktionen
4.949
Direkt hinter der Anweisung Loop über den restlichen Code zu einer marke end springen, die ganz am ende des Codes steht.!
Warum? Dann wird dem Meldeausgang #Bereich_belegt nichts zugewiesen. Dann schon eher so:
Code:
      LOOP  Su

      CLR                               // wenn hier aus Schleife, dann waren alle DBD <> 0
out:  NOT
      =     #Bereich_belegt             // 1 = alle 10 DBD sind belegt
      [COLOR="#0000FF"]SPB   end[/COLOR]

//Wenn ein leeres DBD gefunden wurde, dann steht dessen Adresse in #dwPointer
      L     #dwPointer
      T     #freies_DW                  // DBD-Adresse als P#Adresse.0

[COLOR="#0000FF"]end:  SET[/COLOR]
Ob das Überspringen der 2 Anweisungen tatsächlich was bringt? Dann steht in der TEMP-Variable #freies_DW irgendwas zufälliges - der Wert darin ist aber eh' nur gültig bei #Bereich_belegt = 0. Was schadet also das immer Speichern des Pointers in #freies_DW?

Harald
 

Heinileini

Well-known member
Beiträge
3.729
Punkte Reaktionen
717
Zuviel Werbung?
->Hier kostenlos registrieren
Und wie kann ich sicher sein das auch wirklich jedes Doppelwort überprüft worden ist.
Kannst Du nicht, wenn die Schleife vorzeitig verlassen wird. Dann kannst Du nur sicher sein, dass wahrscheinlich nicht jedes DD überprüft wurde.

In Deinem Code aus #10 verstehe ich nicht, warum die DD-Inhalte mit 1 verglichen werden!? Werden die DDe nie einen anderen Wert als 0 oder 1 enthalten? ("Oversized"?)

Habe ich das richtig verstanden, dass das Progrämmchen feststellen soll ...
1. ob keins der 10 DDe ist belegt (= alle sind frei)
2. ob alle 10 DDe sind belegt (= keins ist frei)
3. ob die 10 DDe z.T. frei sind und Du benötigst dann die Information, welches davon ...
3.1 das erste freie DD oder
3.2 das "nächste" freie DD (bezogen auf was?!) oder
3.3 das letzte freie DD ist?
Du willst den Zeiger auf eines der freien DDe in Form eines Pointers oder lieber als "Index" (0: erstes DD ist frei .. 9: letztes DD ist frei; -1: kein DD ist frei)?

Benötigst Du auch noch die Information, wie viele der DDe frei sind? Ich frage vorsichtshalber schon mal, ehe die nächste Änderung der Aufgabenstellung erfolgt ;)

Edit: da waren wieder einige nicht ganz so langsam wie ich :icon_mrgreen:
 
Zuletzt bearbeitet:
OP
T

tommylik

Well-known member
Beiträge
80
Punkte Reaktionen
0
Hallo an alle,

Vielen Dank für die Ideen habe jetzt eine funktionierende Lösung.

Mfg Tommylik
 
Zuletzt bearbeitet:
Oben