is AR2 dangerous ?

kyoq

Member
Join Date
Sep 2006
Location
Poland
Posts
18
Hi, when I compile FC thet uses AR1 and AR2 I got warning "W Ln 000058 Col 013: Changes of AR2 can destroy local variable accesses in FBs of your project"
is it possible to destroy local variable accesses ? even if I store (at the begining of FC) and restore (at the end of FC) AR's ?

TAR1 #hold_AR1; store
TAR2 #hold_AR2;
LAR1 #hold_AR1; restore
LAR2 #hold_AR2;
 
All function blocks with multiple instance capability use indirect addressing via AR2. For example, say in your FB you declare an INT named Count as the first stat variable. Then,
Code:
L #Count
will actually execute as:
Code:
L DIW[AR2,P#0.0]
(if you type in L DIW[AR2,P#0.0] the editor will convert it back to L #Count for you).
This is why the warning is produced when you modify AR2, if you modify AR2 inside an FB, AR2 will no longer point to the base of the static data and all references to named static variables will access the wrong data.

If you call an FC from an FB, for example
Code:
Call FC1
the code actually produced is as follows:
Code:
	 Call
	 BLD 1
	 =	 L	 4.0
	 TAR2 LD	 0
	 UC	FC	 1
	 LAR2 LD	 0
	 BLD 2
	 End Call

As you can see, prior to calling FC1, AR2 is stored in the FB's temp data area and is restored after calling the FC. You can therefore modify AR2 inside an FC that has been called from an FB without having to save AR2 yourself, the editor has generated code that does that for you.
 
Thanks for the explanation Simon, Always been a bit of a mystery when you need to Save address register contents and when not!
 
thx for explanation, but
I don't know about multiple instance db ?
for sure I'm using instance data block.
I am creating FB33 and variables inside, then DB33 referencing a function block.
 
When you call a function block, you normally (as you have described) specify the instance data block provided for the call and the function block parameters and static data are stored in the instance data block.

From Step7 V2, you can generate "multiple instances", that is you can call a function block in another function block. The block parameters and the static local data of the called function block are then a subset of the static local data of the calling block - you do not have to specify an instance data block in this case.
To declare a multiple instance (of say FB1), you enter the function block in the static data area giving the instance a name and for the data type you would enter FB1.

(Note the majority of this description is taken from Berger's book)

If you copy/paste the following source code and insert it into a source code file and compile it, you can use the block editor to examine my example.

Code:
FUNCTION_BLOCK FB 1
TITLE =
VERSION : 0.1

VAR
  iData : INT ; 
END_VAR
BEGIN
NETWORK
TITLE =
END_FUNCTION_BLOCK

FUNCTION_BLOCK FB 2
TITLE =multiple instance example
VERSION : 0.1

VAR
  fbInstance1 : FB 1; 
  fbInstance2 : FB 1; 
  fbInstance3 : FB 1; 
  fbInstance4 : FB 1; 
  fbInstance5 : FB 1; 
  fbInstance6 : FB 1; 
  fbInstance7 : FB 1; 
  fbInstance8 : FB 1; 
END_VAR
BEGIN
NETWORK
TITLE =instance 1
	  CALL #fbInstance1 ;
	  NOP   0; 
NETWORK
TITLE =instance 2
	  CALL #fbInstance2 ;
	  NOP   0; 
END_FUNCTION_BLOCK
 
Last edited:
If you look behind the scenes, this is what is actually happening
when you call the two instances of FB1 from FB2.
The important action is that AR2 is first saved in local data, the offset to each instances static data is added to AR2 prior to calling FB1. After FB1 has been called, AR2 is restored to it's
saved value for correct static variable access in FB2.

Network 1
Code:
	  Call
	  BLD   14
	  =	 L	  6.0
	  L	 DINO			   //get current instance DB number   
	  T	 LW	 4		   //save in local data
	  CDB					  //swap current global/instance DBs 
	  OPN   DI [LW	 4]	  //open current instance
	  TAR2  LD	 0		   //save AR2 in local data
	  +AR2  P#0.0			  //add offset for instance1 to AR2
	  UC	FB	 1		   //Ar2 now points to base address of instance1
	  LAR2  LD	 0		   //restore Ar2
	  CDB					  //swap current global/instance DB's
	  BLD   15
	  End Call
	  NOP   0

Network 2
Code:
	  Call
	  BLD   14
	  =	 L	  6.0
	  L	 DINO			   //get current instance DB number   
	  T	 LW	 4		   //save in local data
	  CDB					  //swap current global/instance DBs 
	  OPN   DI [LW	 4]	  //open current instance
	  TAR2  LD	 0		   //save AR2 in local data
	  +AR2  P#2.0			  //add offset for instance2 to AR2
	  UC	FB	 1		   //Ar2 now points to base address of instance2
	  LAR2  LD	 0		   //restore Ar2
	  CDB					  //swap current global/instance DB's
	  BLD   15
	  End Call
	  NOP   0
 

Similar Topics

Hi, I have silly question(try to understand Pointer Application) can someone explain this below question. OPN DI10 A DB5.VAR76 FN...
Replies
0
Views
1,238
I am looking for some advice on this FC I just wrote. I have trace numbers that are constantly moved and want to verify that they match. They are...
Replies
7
Views
5,114
Hello I wrote this piece of code to do indirect adressing for a DB using both AR1 and AR2. When I run this code in a FB for situation #Drive_No =...
Replies
5
Views
4,276
Example_1: TAR2 #AR2_TMP L P##VARIABLE TAR2 +D LAR1 A [AR1,P#0.6] //operate with bit L B[AR1,P#0.0] //load 1st BYTE L W[AR1,P#1.0] //LOAD...
Replies
5
Views
2,129
Hi All, I have a question regarding the population of AR2 when a multi instance FB is called. Would I be correct in thinking that the value...
Replies
10
Views
4,011
Back
Top Bottom