Hilfe zur indirekten Adressierung

LittleJack86

Level-1
Beiträge
44
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Guten Mogen allerseits!

Ich weiß schon, zur indirekten Adressierung gibts schon viele Fragen, habe nur nix gefunden was mich glücklich stimmen lässt.

Zur Problemstellung:
Ich habe einen multiinstazfähigen FB, in diesem gibt es u.a. als statische Variable ein Array of char mit 50 Zeichen.
Dieses Array möchte ich Byte für Byte kopieren bis ich ein bestimmtes Zeichen im Array erreicht habe.

Zur Frage:
Kann ich die statischen Variablen generell NUR mit Hilfe eines Any-Zeigers flexibel ansprechen?
...oder wäre es auch einfacher mit einem Pointer möglich?
Weiters, der lokale Bereich, welchen ich z.B. durch "L LB 0" ansprechen kann entspricht NUR den Temp Variablen oder irre ich da?

Ich hätte das mit dem Any-Zeiger mal folgendermaßen zusammengestöpselt (ich befinde mich hier in einem multiinstanzfähigen Baustein):
Code:
//Nummer Instaz-DB ermitteln
      L     DINO                        //Nummer des Instanzdatenbausteins laden
      T     #MeinDB

//Adressregisterversatz ermitteln
      L     #MemAR2                     //Sicherung von AR2 laden
      SRD   3                           //Bit-Adressbereich entfernen
      T     #ByteAdrAR2                 //Byte-Versatz für MultiinstazCalls

//ByteAdresse von MeinArray ermitteln
      L     P##MeinArray                //Pointer mit meinem Array laden
      SRD   3                           //Bit-Adressbereich entfernen
      L     #ByteAdrAR2                 //Byte-Adresse des AR2 laden
      +D                                //ByteAdr AR2 zur ByteAdr des Pointers addieren
      INC   1                           //Adresse um ein Byte erhöhen (Geradzahliges Bytemuster)
      T     #ByteAdrMeinArray           //Ergibt die Byte-Adresse im Multiinstaz DB


//Pointer für MeinArray bauen
      LAR1  P##MeinZeiger               //Adresse des Zeigers ins Adressregister laden
      L     W#16#10
      T     LB [AR1,P#0.0]
      L     W#16#2                      //Typ BYTE
      T     LB [AR1,P#1.0]
      L     1                           //ein Byte lang
      T     LW [AR1,P#2.0]
      L     #MeinDB                     //Aktueller Instanz-DB
      T     LW [AR1,P#4.0]
      L     #ByteAdrMeinArray           // <<-- kann ich nun jeweils um 1 erhöhen um das Array Byte-weise zu durchlaufen
      SLD   3
      T     LD [AR1,P#6.0]
      L     B#16#85                     //Speicherbereich (hier Instanz-DB)
      T     LB [AR1,P#6.0]

//Zeichen in MeinArray-Indirekt prüfen
      L     P##MeinZeiger           
      L     'X'
      ==I                                //schauen ob das aktuelle Zeichen ein X ist
      .
      .
      .

...die Variable #ByteAdrMeinArray kann ich ja nun jeweils um eins erhöhen um im Array of char zum nächsten Zeichen zu kommen, oder?
...und wo ich mir auch nicht sicher bin, ob Instaz DB beim Speicherbereich richtig ist, was macht in dem Fall den Unterschied, könnte ich nicht genau so einen Zeiger bauen mit einfach nur DB, und auf einen Instanz-DB zugreifen?

Ich danke euch schon mal für die Hilfe!

Liebe Grüße
LiJ
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
Kann ich die statischen Variablen generell NUR mit Hilfe eines Any-Zeigers flexibel ansprechen?
Nein !

...oder wäre es auch einfacher mit einem Pointer möglich?
Ja - Klar ...

Weiters, der lokale Bereich, welchen ich z.B. durch "L LB 0" ansprechen kann entspricht NUR den Temp Variablen oder irre ich da?
Korrekt so - nur der TEMP-Bereich.

Ich muss allerdings Tigerente zustimmen. SCL ist hier nicht nur der einfachste sondern auch der übersichlichste und sicherlich auf jeden Fall der sinnvollste Weg.

Gruß
Larry
 
leider steht mir SCL nicht zur Verfügung! :cry:

und wie würd ich das ohne SCL einfacher bzw. schöner lösen können? irgendwie steh ich da wohl auf der Leitung
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja ...
Den Pointer auf dein Array laden und ins AR1 transferieren.
Für Multi-Instanz den Offset-Versatz vom AR2 noch mit drauf rechnen.
Das DIB an Pointer-Adresse laden.
Damit machen, was du damit machen willst.
Ggf. das AR1 um p#1.0 (für Byte) erhöhen und erneut lesen.
Wichtig hier : Beachte, dass deine Schleife irgendwann einmal beendet sein muß.

Gruß
Larry
 
Ja ...
Den Pointer auf dein Array laden und ins AR1 transferieren.
Für Multi-Instanz den Offset-Versatz vom AR2 noch mit drauf rechnen.
Das DIB an Pointer-Adresse laden.
Damit machen, was du damit machen willst.
Ggf. das AR1 um p#1.0 (für Byte) erhöhen und erneut lesen.
Wichtig hier : Beachte, dass deine Schleife irgendwann einmal beendet sein muß.

Gruß
Larry

Ist jetzt vermutlich eine blöde Frage, aber ganz sicher bin ich mir hald nicht: muss ich den Instanz-DB extra öffnen um mit DIB auf ihn zugreifen zu können?

Ich hätte das jetzt dank deiner Hilfe folgendermaßen gelöst:
(gibts da Einwende? die Funktion wird dann noch umfangreicher habe nur als Bsp. den Vergleich mit 'x' eingefügt)
Code:
      L     P##MeinArray                //Mein Array laden
      SRD   3                           //Bit-Adressbereich entfernen
      L     #ByteAdrAR2                 //Byte-Adresse des AR2 laden
      +D                                //ByteAdr AR2 zur ByteAdr des Pointers addieren
      T     #MeinZeiger

      L     0
      T     #Schleifenzaehler           //Schleifenzähler initialisieren


NEXT: L     #MeinZeiger                 //Adresse des ersten Bytes im Array
      L     #Schleifenzaehler           //Aktuelle Schleifenzahl (Versatz um ein Byte je Durchlauf)
      +D    
      SLD   3                           //Berechnete Byte-Adresse um den Bit-Bereich erweitern
      LAR1                              //Adresse ins AR1 laden um indirekt Adressieren zu können

      L     DIB [AR1,P#0.0]             //Aktuelles Zeichen im Array (Indirekt)...
      L     'X'                         //...mit z.B. X...
      ==I                               //...vergleichen
      S     #ZeichenGefunden


      L     #Schleifenzaehler
      INC   1
      T     #Schleifenzaehler           //Schleifenzähler um eins erhöhen


      UN    #ZeichenGefunden
      SPB   NEXT
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier mal ein Beispiel für das Zerlegen eines Telegramms mit fester Länge / Struktur.

Code:
  VAR_INPUT
    Enable:BOOL;
    Telegramm:STRING[12];
  END_VAR
   
  VAR_TEMP
    tmpTele:STRING[12];
    tmpKennung:STRING[3];
    tmpAuftrag:STRING[3];
    tmpInfo:STRING[4];
  END_VAR

BEGIN

//Telegrammstruktur: ABC.xxx.1234 
//                   123456789012
//                   (Kennung.Auftrag.Info)


IF Enable THEN 
    
    tmpTele:=''; //Initialisieren
    tmpKennung:='';
    tmpAuftrag:='';
    tmpInfo:='';
    
    tmpTele:=Telegramm; //Telegramm einlesen
    
    tmpKennung:=MID(IN:=tmpTele,L:=3,P:=1); //Kennung auslesen
    tmpAuftrag:=MID(IN:=tmpTele,L:=3,P:=5); //Auftrag auslesen
    tmpInfo:=MID(IN:=tmpTele,L:=4,P:=9);    //Info auslesen

END_IF;
 
Zurück
Oben