# Das Adressregister - tolle Sache, aber was gibt es zu beachten



## LittleJack86 (21 Januar 2011)

Erst mal einen guten Morgen! 

Ich habe schon öfter gelesen, dass es bei der Verwendung der Adressregister notwendig ist, zuvor ihren Inhalt zu sichern und nach der Verwendung den Inhalt wieder herzustellen. 
Nur wann sollte man dies machen? Nur bei der Verwendung in Multiinstanzen? 
Weiters, bei der indirekten Adressierung in Multiinstanzen muss man ja einen Versatz, welcher im AR2 steht, mit einbeziehen, oder? 

Was gibt es denn generell und bei spezielleren Anwendungen (z.B. Multiinstanz) der Adressregister zu beachten? 

Schon mal vielen Dank für die Info! 
Flo


----------



## M-Ott (21 Januar 2011)

LittleJack86 schrieb:


> Nur wann sollte man dies machen? Nur bei der Verwendung in Multiinstanzen?


Zuerst einmal muss man unterscheiden: Die S7 hat zwei Adressregister, sinnigerweise Adressregister 1 (AR1) und Adressregister 2 (AR2) genannt.
AR1 wird vom System nicht verwendet und kann vom Benutzer immer frei verwendet werden, auch in FBs und sogar in Multiinstanzen. Wenn man AR1 verwendet, muss man den Inhalt vorher nicht sichern.
Bei AR2 ist das anders und damit zu Deiner zweiten Frage:


LittleJack86 schrieb:


> Weiters, bei der indirekten Adressierung in Multiinstanzen muss man ja einen Versatz, welcher im AR2 steht, mit einbeziehen, oder?


In einem FB steht in AR2 der Versatz, ab welcher Adresse die Daten für den aktuellen Aufruf im IDB stehen. Wenn es sich nicht um einen Multiinstanz-Aufruf handelt und der FB seinen eigenen IDB hat, steht hier also P#0.0. Bei einem Multiinstanz-Aufruf ändert sich das entsprechend.
Bei jedem symbolischen Zugriff auf den IDB (also jeder Zugriff auf IN, OUT INOUT oder STAT) wird das AR2 zur Adresse im Variablendeklarationsteil des Bausteins dazugezählt, auch bei nicht-Multiinstanz-Aufrufen. Wenn man also mit dem AR2 in einem FB arbeitet (was man vermeiden sollte), dann muss man vorher den Inhalt sichern und vor dem nächsten symbolischen Zugriff auf den IDB wieder zurückschreiben, da sonst die Zugriffe verschoben sind.


----------



## LittleJack86 (21 Januar 2011)

M-Ott schrieb:


> In einem FB steht in AR2 der Versatz, ab welcher Adresse die Daten für den aktuellen Aufruf im IDB stehen. Wenn es sich nicht um einen Multiinstanz-Aufruf handelt und der FB seinen eigenen IDB hat, steht hier also P#0.0. Bei einem Multiinstanz-Aufruf ändert sich das entsprechend.
> Bei jedem symbolischen Zugriff auf den IDB (also jeder Zugriff auf IN, OUT INOUT oder STAT) wird das AR2 zur Adresse im Variablendeklarationsteil des Bausteins dazugezählt, auch bei nicht-Multiinstanz-Aufrufen. Wenn man also mit dem AR2 in einem FB arbeitet (was man vermeiden sollte), dann muss man vorher den Inhalt sichern und vor dem nächsten symbolischen Zugriff auf den IDB wieder zurückschreiben, da sonst die Zugriffe verschoben sind.


 
Damit ich das jetzt richtig verstehe: 
Also wenn ich in einem FB (egal ob Multi oder nicht) symbolisch auf den IDB zugreife, wird IMMER AR2 zur Adresse hinzugezählt. Soweit mal richtig?

Dies ändert nur in einem NICHT Multi-FB nichts an der Adresse, da AR2 NULL ist. 
Wenn ich aber in einem Multiinstanzaufruf größer als dem ersten Aufruf bin, so steht im AR2 der Versatz bis zum jeweiligen Datenbereich im IDB, welcher beim symbolischen Zugriff auf den IDB mit eingerechnet wird. 

Das Hinzurechnen geschieht allerdings automatisch von der Steuerung. In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?

Wenn ich also nicht direkt den Inhalt des AR2 überschreibe (z.B. mit LAR2) dann brauche ich es auch nicht zu sicher? oder kann ich es auch anderwertig überschreiben? 
Und das AR1 kann ich auch immer ändern ohne es zu sichern?


----------



## M-Ott (21 Januar 2011)

LittleJack86 schrieb:


> Damit ich das jetzt richtig verstehe:
> Also wenn ich in einem FB (egal ob Multi oder nicht) symbolisch auf den
> IDB zugreife, wird IMMER AR2 zur Adresse hinzugezählt. Soweit mal richtig?


Ja.


LittleJack86 schrieb:


> Dies ändert nur in einem NICHT Multi-FB nichts an der Adresse, da AR2
> NULL ist.


Wenn es nicht geändert wurde.


LittleJack86 schrieb:


> Wenn ich aber in einem Multiinstanzaufruf größer als dem ersten Aufruf bin,
> so steht im AR2 der Versatz bis zum jeweiligen Datenbereich im IDB,
> welcher beim symbolischen Zugriff auf den IDB mit eingerechnet wird.


Fast richtig. Wenn der aufrufende FB eigene Variable mitbringt, beginnt der erste Aufruf nicht bei Adresse 0.0.


LittleJack86 schrieb:


> Das Hinzurechnen geschieht allerdings automatisch von der Steuerung.


Ja.


LittleJack86 schrieb:


> In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?


Nein. Mit LB greifst Du immer auf die temporären Lokaldaten zu. Aber wenn Du z.B. mit L D*I*W xx auf die jeweilige Instanz zugreifen möchtest, musst Du den Versatz berücksichtigen.


LittleJack86 schrieb:


> Wenn ich also nicht direkt den Inhalt des AR2 überschreibe (z.B. mit LAR2) dann brauche ich es auch nicht zu sicher? oder kann ich es auch anderwertig überschreiben?


Wenn Du das AR2 nicht veränderst, musst Du es auch nicht sichern.


LittleJack86 schrieb:


> Und das AR1 kann ich auch immer ändern ohne es zu sichern?


Ja.


----------



## LittleJack86 (21 Januar 2011)

O.K. jetzt habe ich's verstanden. 

VIELEN DANK für die Info!


----------



## PN/DP (21 Januar 2011)

*Alle Register werden systemseitig verwendet!*

Alle Register (AR1, AR2, DB- und DI-Register, Akkus) werden je nach Situation systemseitig verwendet!
Das kann man sehr leicht in der Step7-Hilfe und den diversen Step7-Programmierhandbüchern nachlesen.

Die *Step7-Hilfe > Hilfethemen... > Index: Adressregister* ergibt folgenden informativen Beitrag:


> *Hinweise zur Änderung von Register-Inhalten*
> 
> Wenn Sie die im Anschluss beschriebenen Programmiermöglichkeiten und gleichzeitig die genannten Register/Akkus nutzen, müssen Sie selbst für eine Wiederherstellung der Register- bzw. Akku-Inhalte sorgen, da es sonst zu einem Fehlverhalten kommen kann.
> 
> ...


Der Hilfe-Beitrag "Vermeiden von Fehlern beim Aufrufen von Bausteinen" *beschreibt noch ausführlicher die Situationen*, in denen Register modifiziert werden.

Harald


----------



## M-Ott (21 Januar 2011)

> vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC
> FB- und Multiinstanz-CALL
> Strukturkomponente eines Formalparameters als Operand innerhalb eines FC oder FB
> Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB




Wenn ich mich nicht irre, sind das alles Sachen, die nur das DB-Register oder das AR*2* ändern. Welches davon ändert das AR*1*? Oder ist da womöglich ein Schreibfehler in der Überschrift?


----------



## Verpolt (21 Januar 2011)

________________________-


----------



## LittleJack86 (21 Januar 2011)

PN/DP schrieb:


> Alle Register (AR1, AR2, DB- und DI-Register, Akkus) werden je nach Situation systemseitig verwendet!
> Das kann man sehr leicht in der Step7-Hilfe und den diversen Step7-Programmierhandbüchern nachlesen.


 
Hallo, 
also die Hilfe dazu kenne ich, die habe ich auch gelesen, allerdings nicht so wirklich verstanden. Weshalb ich diesen Betrag begonnen habe. 

Ich würd an dieser Stelle aber gerne darauf eingehen:





PN/DP schrieb:


> vollqualifizierter DB-Zugriff (z.B. DB20.DBW10) als Aktualparameter für FC


Was soll das genau bedeuten?





PN/DP schrieb:


> FB- und Multiinstanz-CALL


..ist mir jetzt glaube ich klar





PN/DP schrieb:


> Strukturkomponente eines Formalparameters als Operand innerhalb eines FC oder FB
> Strukturkomponente eines Formalparameters als Aktualparameter für FC oder FB


...und da weiß ich auch nicht so recht was denn gemeint ist.


----------



## M-Ott (21 Januar 2011)

LittleJack86 schrieb:


> Was soll das genau bedeuten?.


z.B. DB20.DBW10 als IN, INOUT oder OUT-Parameter eines FC (ändert das DB-Register)


LittleJack86 schrieb:


> ..ist mir jetzt glaube ich klar.





LittleJack86 schrieb:


> ...und da weiß ich auch nicht so recht was denn gemeint ist.


Wenn Du eine Struct als FB- oder FC-Parameter angibst, ändert sich jedesmal, wenn Du auf einen Teil davon zugreifst, das AR1, Du musst also in diesem Fall darauf aufpassen, dass ein evtl. von Dir dort hinterlegter Wert nicht überschrieben wird.


----------



## Jochen Kühner (21 Januar 2011)

LittleJack86 schrieb:


> D
> Das Hinzurechnen geschieht allerdings automatisch von der Steuerung. In welchen Fällen muss dieser Versatz dann von mir aktiv berücksichtigt werden? Wenn ich z.B. mit LB auf den Lokal-Datenbereich zugrefen möchte?



Mann kann dies schön sehen wenn man sich den MC7 Code der auf der Steuerung ist wieder in AWL zurückwandelt:

aus z.b.:


```
U     #INIT
      R     #TRIGGERABRUCH_GESENDET
      R     #TRIGGER_GESENDET
```

wird dann:


```
U     DIX[AR2,P#8.1]
      R     [AR2,P#64.3]  
      R     [AR2,P#64.2]
```

und aus zugriffen an höhren adressen wird (bb liegt bei 60000)


```
L    #bb
```

wird 


```
TAR2  LD0           
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      +AR2  P#4090.0      
      L     DIW[AR2,P#2740.0]
      LAR2  LD0
```


----------



## LittleJack86 (21 Januar 2011)

M-Ott schrieb:


> z.B. DB20.DBW10 als IN, INOUT oder OUT-Parameter eines FC (ändert das DB-Register)


...also so geschrieben ist mir das eh klar, ändert aber NUR das DB-Register. 
Noch was dazu, der übergebene Wert z.B. DB20.DBW10 als INOUT-Parameter wird aber beim Aufruf des FC in den Temporären bereich übergeben und ändert somit nur direkt beim aufruf des FC das DB-Register, oder wird das DB-Register immer geändert sobald ich im FC diese Variable anspreche? (habe ich eigentlich noch nie so in einem FC verwendet)



M-Ott schrieb:


> Wenn Du eine Struct als FB- oder FC-Parameter angibst, ändert sich jedesmal, wenn Du auf einen Teil davon zugreifst, das AR1, Du musst also in diesem Fall darauf aufpassen, dass ein evtl. von Dir dort hinterlegter Wert nicht überschrieben wird.


kannst du mir dazu ein kurzes Bespiel geben? Dass ist mir noch nicht ganz verständlich.


----------



## PN/DP (21 Januar 2011)

Kleine Abschwächung:
Im Gegensatz zum AR2 muß man AR1 nicht vor der Verwendung für das System sichern und wiederherstellen.
Das System erwartet keinen bestimmten Inhalt im AR1. Wenn es AR1 verwendet, dann initialisiert es das AR1 auch jedesmal selbst.

Man muß nur aufpassen wenn man selbst AR1 verwendet (z.B. in einer Schleife!) und eine der 4 genannten Situationen hat. Dann muß man damit rechnen, daß das System rücksichtslos "meinen" AR1-Inhalt verändert hat. Man muß den eigenen AR1-Inhalt selber vor dem System retten.

@LittleJack86
"vollqualifizierter DB-Zugriff" ist, wenn in der Zugriffsadresse die DB-Nummer mit enthalten ist: L DB20.DBW10
Dann macht das System bei jedem Zugriff implizit ein AUF DBxx.
L DBW10 ohne Angabe der DB-Nummer ist ein "unqualifizierter" DB-Zugriff auf den gerade (zufällig?!) geöffneten DB.

"Strukturkomponente eines Formalparameters"
Wenn z.B. eine Struktur an einen FC oder FB übergeben wird, dann wird tatsächlich nur die Anfangsadresse als Pointer übergeben. Wenn nun innerhalb der FC oder FB auf ein Element der übergebenen Struktur zugegriffen wird, dann muß "das System" selber indirekt adressieren. D.h. in etwa: AR1 wird mit dem übergebenen Pointer geladen und zeigt damit auf den Anfang der Struktur, für den Zugriff auf ein Element wird dann noch der bekannte Offset zum AR1 adressiert.
Wenn die übergebene Struktur aus einem DB stammt (was fast immer der Fall ist), dann muß auch das DB-Register für den indirekten Zugriff auf die Struktur vom System verwendet werden. Das DB-Register enthält nach dem Zugriff die DB-Nummer der übergebenen Struktur.
Diese normalerweise nicht sichtbaren indirekten Zugriffe auf Strukturkomponenten verbrauchen übrigens unheimlich viel Programmspeicher für die Adressberechnung, ich meine das waren je Zugriff ca. 42 Byte Code. Deshalb sollte man bei Übergabe von Strukturen diese vor der Verwendung zuerst in die temporären Lokaldaten umkopieren und dann auf diese lokale Kopie zugreifen.

Harald


----------



## LittleJack86 (21 Januar 2011)

Jetzt ist mir das Ganze schon viel besser verständlich. 
Einmal Danke an alle für eure Antworten! 

@Jochen Kühner
Diese Ansicht auf den Code zeigt schon sehr gut wie die SPS die Adressen verarbeitet. 

@PN/DP
Dir natürlich auch vielen Dank für die Erklärung! 
Du hast ja den Aufwand für die SPS bei einem Zugriff mit Structurkomponenten angesprochen, dazu fällt mir noch eine Frage ein welche ich mir schon länger gestellt habe. 
Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich 
DB10.DBW 100 anspreche oder wenn ich 
MW100 anspreche? 

Florian


----------



## M-Ott (21 Januar 2011)

LittleJack86 schrieb:


> Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich DB10.DBW 100 anspreche oder wenn ich
> MW100 anspreche?


 
Wenn Du mit Aufwand "Zeitaufwand" meinst: Ja, es ist mehr Aufwand (zumindestens bei der S7-300).

Wenn Dich das ganze im Detail interessiert, kannst Du Dir beim Siemens-Support die Operationslisten herunterladen, da steht die detailierte Ausführungszeit für jede Anweisung drin.


----------



## LittleJack86 (21 Januar 2011)

Ja meinte ich, es äußert sich eh jeder Aufwand in Zeit. Die Liste werd ich mach nachlesen. 
Auf die Frage bin ich gekommen weil ich schon öfter mal gesehen hab das Werte in einen DB geschrieben werden (so als Merkerersatz) obwohl dies eigentlich nicht wirklich notwendig gewesen wäre. Es vermutlich nur aus dem Grund geschehen ist damit man das Programm problemlos in eine Steuerung kopieren kann ohne auf die Belegung der Merker eingehen zu müssen (was natürlich auch ein Grund sein kann). 
DANKE


----------



## PN/DP (21 Januar 2011)

LittleJack86 schrieb:


> Weißt du evtl. ob es für die SPS mehr Aufwand ist wenn ich
> DB10.DBW 100 anspreche oder wenn ich
> MW100 anspreche?


Die Operations-Ausführungszeiten sind CPU-abhängig. Bei den aktuellen S7-300 CPU besteht kein Unterschied bei der Ausführungszeit einer Ladeoperation, egal ob auf ein Merkerwort (L MW100) oder vollqualifiziert auf ein DB-Wort (L DB10.DBW100) zugegriffen wird. Bei älteren S7-300 CPU hat das Laden eines DB-Wortes mehr als doppelt so lange wie das Laden eines Merkerwortes gedauert (wegen der implizit enthaltenen Operation AUF DBxx).

Die Ladeoperationen sind aber je nach Operand unterschiedlich lang, L MWxx benötigt 2 Byte Programmspeicher, L DBxx.DBWxx benötigt 6 Byte Programmspeicher.

Details siehe in den Operationslisten der jeweiligen CPU - dabei genaue Bestell-Nummer beachten!

Harald


----------



## M-Ott (21 Januar 2011)

PN/DP schrieb:


> Die Operations-Ausführungszeiten sind CPU-abhängig. Bei den aktuellen S7-300 CPU besteht kein Unterschied bei der Ausführungszeit einer Ladeoperation,...


Das trifft für solche CPUs zu, die bereits mit der Firmwareversion 3.0 erschienen sind. Die aktuellen Kompakt-CPUs haben alle noch ältere Fimrware und somit unterschiedliche Zugriffszeiten.


----------



## M.Arlitt (4 Juli 2014)

Wie schaut es denn aus, wenn ich einen AR2 Zugriff innerhalb eines FCs mache, dieser FC wird in oberster Instanz im OB1 gecallt.

Der FC hat sowohl Eingangs und Ausgangsparameter

Führt das zu Problemen bei der Benutzung mit AR2?


----------



## SoftMachine (4 Juli 2014)

.
Nur bei FB´s, bei FC´s dürftest du keine Probleme habenm, siehe Beitrag#6 Absatz 4 .


----------



## M.Arlitt (4 Juli 2014)

Um ganz sicher zu gehen habe ich jetzt meinen Temporären Speicher kontrolliert im FC, der endet bei L24.0 und habe dann um meinen Code mit AR2 die Befehle:


```
TAR2 LD24

[...]


LAR2 LD24
```

gebastelt. DAnn bin ich ja auf der sicheren Sete...


----------



## SoftMachine (4 Juli 2014)

.
Naja,
auf jeden Fall solltest du dich auch über den Aufbau des L-Stack und den direkten Zugriff darauf informieren.


----------



## M.Arlitt (4 Juli 2014)

Ich weiß was du meinst ;-)
Sollte so kein Problem darstellen, Fakt ist wenn ich aus Jux und dollerei in diesem FC einen FB mit 32 binären Eingängen in KOP aufrufen, dann würde er ja beim Umstellen auf AWl auch zeigen das er dann auf die Lokaldaten L24.0 bis L27.7 schreibt. Solange ich innerhalb des obig erwähnten TAR2 - LAR2 keine KOP-FUP Anweisungen mit FC/FB aufruf habe klappt es aber.


----------



## PN/DP (4 Juli 2014)

M.Arlitt schrieb:


> Um ganz sicher zu gehen habe ich jetzt meinen Temporären Speicher kontrolliert im FC, der endet bei L24.0 und habe dann um meinen Code mit AR2 die Befehle:
> 
> 
> ```
> ...


Du könntest auch einfach in TEMP eine DWORD-Variable AR2Save erstellen, dann wäre das auch sauber.

```
TAR2 #AR2Save

[...]

LAR2 #AR2Save
```

Harald


----------



## M.Arlitt (4 Juli 2014)

wie er gesagt! warum mach ich mir selber immer das leben schwer jetzt muss ich gleich die Änderung wieder an alle Kollegen schicken 

EDITH sagt: Siemens is ja doch manchmal schlau, gerade als ich das geändert habt und die Deklarationszeile eingefügt habe meckert er sofort rum, das es im AWL Code ja schon einen Lokaldatenzugriff auf diesen Bereich gibt


----------



## BlemaTue (2 Dezember 2016)

M-Ott schrieb:


> Zuerst einmal muss man unterscheiden: Die S7 hat zwei Adressregister, sinnigerweise Adressregister 1 (AR1) und Adressregister 2 (AR2) genannt.
> AR1 wird vom System nicht verwendet und kann vom Benutzer immer frei verwendet werden, auch in FBs und sogar in Multiinstanzen. Wenn man AR1 verwendet, muss man den Inhalt vorher nicht sichern.
> Bei AR2 ist das anders und damit zu Deiner zweiten Frage:
> 
> ...



DasAR1 wird vom System verwendet. siehe Step-7 Hilfe unter dem "Index Register-Inhalt"


----------

