The statements available for working with the address registers AR1 and AR2 are listed in Table 4.8. A graphic representation of the data flow between the operand areas, the address registers AR1 and AR2, and the accumulator 1 is shown in Fig.
4.7. All statements are executed independent of conditions, and do not influence the status bits.
Table 4.8 Overview of address register functions Operation Operand Function
LAR1 LAR1 LAR1 LAR1
Operand Pointer AR2
Load address register AR1 with the content of accumulator 1 Load address register AR1 with the content of the operand Load address register AR1 with the pointer
Load address register AR1 with the content of address register AR2 LAR2
LAR2 LAR2
Operand Pointer
Load address register AR2 with the content of accumulator 1 Load address register AR2 with the content of the operand Load address register AR2 with the pointer
TAR1 TAR1 TAR1
Operand AR2
Transfer the content of address register AR1 to accumulator 1 Transfer the content of address register AR1 to the operand Transfer the content of address register AR1 to address register AR2 TAR2
TAR2 Operand
Transfer the content of address register AR2 to accumulator 1 Transfer the content of address register AR2 to the operand TAR Swap the contents of the address registers
+AR1
+AR1 Pointer
Add the content of accumulator 1 to address register AR1 Add the pointer to address register AR1
+AR2
+AR2 Pointer
Add the content of accumulator 1 to address register AR2 Add the pointer to address register AR2
Loading into an address register
The LARn statement loads an area pointer into address register ARn (n = 1 or 2). You can select an area-internal or cross-area pointer or a doubleword from operand ar- eas (bit memories, temporary local data, global data, and instance data) as the source. The content of the doubleword must correspond to the format of an area pointer.
If you do not specify an operand, LARn loads the content of accumulator 1 into address register ARn.
Using the LAR1 AR2 statement, you copy the content of address register AR2 into address register AR1.
Transferring from an address register
The TARn statement transfers the complete area pointer from address register ARn (n = 1 or 2). You can specify a doubleword from operand areas (bit memories, tem- porary local data, global data, and instance data) as the destination.
If you do not specify an operand, TARn transfers the content of address register ARn into accumulator 1. The previous content of accumulator 1 is shifted into accumu- lator 2 during this procedure; the previous content of accumulator 2 is lost.
Using the TAR1 AR2 statement you copy the content of address register AR1 into address register AR2.
Swap address register contents
The TAR statement swaps the contents of address registers AR1 and AR2. Fig. 4.8 (top) shows an example of application of the statement.
Fig. 4.7 Statements for working with address registers xx in the statements stands for:
Address register AR1
Address register
x = bit address y = byte address Z = area AR2
Statements in association with the address registers
Note: The system blocks BLKMOV and UBLKMOV are available for transferring larger data areas.
Example of swapping address register contents 8 bytes of data are transferred between the
memory area starting at %MB100 and the data area starting at %DB20.DBB200. The transfer direction is determined by bit memory %M126.6. The contents of the address registers are swapped if %M126.6 has the signal state “0”.
If you wish to transfer data between two da- ta blocks in this manner, also load the two data block registers together with the ad- dress registers (using OPN and OPNDI) and swap the contents where appropriate using the TDB statement.
LAR1 P#M100.0 LAR2 P#DBX200.0 OPN %DB20 A %M126.6 JC Swap TAR
Swap: L D[AR1,P#0.0]
T D[AR2,P#0.0]
L D[AR1,P#4.0]
T D[AR2,P#4.0]
Example of adding a pointer to the address register A data area of length #Number_ data in data
block %DB14 is compared with the #Refer- ence_value tag word-by-word starting at da- ta word %DBW20. If the reference value is larger than the value in the array, a memo- ry bit is to be set to “1” starting at bit mem- ory %M10.0, otherwise to “0”.
OPN %DB14 LAR1 P#DBX20.0 LAR2 P#M10.0 L #Number_data Loop: T #Loop_counter L #Reference_value L W[AR1,P#0.0]
>I
= [AR2,P#0.0]
+AR1 P#2.0 +AR2 P#0.1
L #Loop_counter LOOP Loop
Example of adding the accumulator content to the address register In data block %DB14, the 16 bytes are to be
deleted whose addresses are calculated from the pointer in bit memory doubleword
%MD220 and a (byte) offset in memory byte
%MB18. Prior to addition to AR1, the content of %MB18 must be aligned (SLW 3).
OPN %DB14 LAR1 %MD220 L %MB18 SLW 3 +AR1 L 0
T DBD[AR1,P#0.0]
T DBD[AR1,P#4.0]
T DBD[AR1,P#8.0]
T DBD[AR1,P#12.0]
Fig. 4.8 Examples of register-indirect addressing with STL
Addition to address register
A value can be added to the address registers, e.g. to increment the address of an operand in program loops each time the loop is executed. You can either enter the value as a constant (as area-internal pointer) for the statement, or it is located in the right word of accumulator 1. The type of pointer present in the address register (area-internal or cross-area) and the operand area are retained.
The +AR1 P#y.x and +AR2 P#y.x statements add a pointer to the specified address register. Note that the maximum size of the area pointer is P#4095.7 with these statements. If a value larger than P#4095.7 is present in the accumulator, the num- ber is interpreted as a fixed-point number in two's complement and subtracted. Fig.
4.8 (middle) shows an example of application of the statements.
The +AR1 and +AR2 statements interpret the value present in accumulator 1 as a number in integer format, expand it with the correct sign to 24 bits, and add it to the content of the address register. A pointer can also be reduced in this manner. Upward or downward violation of the maximum range of the byte address (0 to 65 535) has no further effects: The highest bits are “truncated” (Fig. 4.9).
Note that the bit address is present in bits 0 to 2. If you wish to already increment the byte address in accumulator 1, you must add starting with bit 3 (shift the value to the left by 3 digits). Fig. 4.8 (bottom) shows an example of application of the statement.
Note: The system block FILL is available for filling in larger data areas with bit pat- terns.
Fig. 4.9 Addition to address register Addition to address register
Accumulator 1
Address register
1 0 0 0 0 Z Z Z 0 0 0 0 0 y y y S S S S S S S S
y y y y y y y y S y y y y y y y
S y y y y y y y
y y y y y x x x y y y y y x x x
y y y y y x x x Is not considered
Notes on use of address register AR1
STL uses address register AR1 to access block parameters which are transferred as DB pointers. With functions (FC), these are all block parameters with complex data type, and with function blocks (FB), these are in/out parameters with complex data type.
If you therefore access such a type of block parameter, e.g. in order to scan a bit com- ponent of a structure or to write an INT value to an array component, the content of address register AR1 is changed and – as a side note – also the content of the DB reg- ister. This also applies if you “pass on” block parameters with this data type to called blocks.
If you use address register AR1, access to a block parameter as described above must not be carried out between loading of the address register and indirect addressing. Otherwise you must save the content of AR1 prior to access, and load it again following access (see Fig. 4.10 top).
Notes on use of address register AR2
With function blocks with “multi-instance capability”, STEP 7 uses address register AR2 as the “base address register” for instance data. When calling a single instance, P#DBX0.0 is present in AR2 and all access operations to block parameters or static local data in the FB use the register-indirect, area-internal addressing with operand area DI via this register.
Calling of a local instance increases the “base address” with +AR2 P#y.x so that access is possible relative to this address within the called function block which uses the instance data block of the calling function block. In this manner, function blocks can be called either as an independent instance or as a local instance (and in this case at any position in a function block, and also more than once).
If you therefore wish to use address register AR2 in a function block with
“multi-instance capability”, you must previously save the content and then restore it following use. You must not program an access operation to block parameters or static local data in the area in which you are working with the address register AR2 (see Fig. 4.10 bottom).
With a function block without “multi-instance capability”, the program editor does not use address register AR2. The multi-instance capability can be activated or deactivated in the block attributes for a function block generated via a source file where the keyword CODE_VERSION1 is used.
There are no limitations to working with the address register AR2 within functions (FC).
Notes on absolute addressing of static local data
Static local data and block parameters are normally addressed symbolically in the program of the “own” function block. In the case of absolute addressing, you must note that the function block can be called either as a single instance or as a local instance.
The address of the block parameters and static local data specified in the interface of the function block is the offset from the beginning of the instance data. It applies if you call the function block as a single instance with a separate instance data block;
assignment of the data operands then commences at address byte zero.
Example “Save address register AR1”
Temp
AR1Memory : DWORD DBMemory : WORD ...
Declaration of used intermediate memories
...
LAR1 P#y.x OPN DBz ...
Any indirect addressing with AR1 and DB register
L DBNO T #DBMemory TAR1 #AR1Memory
Save register contents
L “Motor1”.Actual_value Access to a tag with complex data type OPN DB[#DBMemory]
LAR1 #AR1Memory
Restore register contents
T DBW[AR1,P#0.0] Save loaded value Example “Save address register AR2”
Temp
AR2Memory : DWORD DIMemory : WORD ...
Declaration of used intermediate memories
L DINO T #DIMemory TAR2 #AR2Memory
Save register contents
...
LAR2 P#y.x OPN DIz ...
Any indirect addressing with AR2 and DI register
OPN DI[#DIMemory]
LAR2 #AR2Memory
Restore register contents
L #Local_tag Access to block parameters and local tags Fig. 4.10 Examples of saving address registers
Example: A 16-bit tag “Setpoint” in the static local data has the address 32.0, which can be read in the block interface in the Offset column following compilation of the function block. You can address this tag in absolute mode with %DIW32 in the func- tion block's program. However, this only works if you call the function block as a sin- gle instance.
If you call a function block as a local instance, its data is present “in the middle” of the instance data block of the calling block (the “multi-instance”). The offset from the start of the multi-instance data is present in address register AR2. The absolute address of a local tag is then the total of the contents of address register AR2 and the address in the called function block (of the local instance).
Example: A 16-bit tag “Setpoint” in the static local data has the address 32.0. This is the offset from the start of the local instance data. The offset from the start of the multi-instance data of the calling function block is present in address register AR2.
The absolute address of this tag is then DIW[AR2,P#32.0] in the program of a func- tion block with multi-instance capability.
Limitations when addressing static local data
In the case of function blocks without multi-instance capability, you can use all statements described in this chapter without limitation.
In the case of function blocks with multi-instance capability, the program editor ac- cesses instance data addressed symbolically by means of the address register AR2, i.e. all access operations are carried out indirectly. Symbolic addressing of instance data is not possible in conjunction with the address registers or further indirect ad- dressing, since in this case the instance data would be addressed indirectly twice.
Program in function block without multi-in- stance capability
Program in function block with multi-in- stance capability
Program in the function block with multi-instance capability and absolute addressing Static
Pointer : DWORD ...
Static
Pointer : DWORD ...
Temp
tPointer : DWORD
Static Offset Pointer : DWORD 32.0 ...
L MW[#Pointer]
L #Pointer T #tPointer
L MW[#tPointer] L MW[DID32]
LAR1 #Pointer L #Pointer LAR1
LAR1 %DID32
TAR1 #Pointer TAR1
T #Pointer
TAR1 %DID32
Fig. 4.11 Examples of use of local data as area pointer
If you wish to use local data addressed symbolically in function blocks with multi- instance capability as pointers, you must use a “detour” via an intermediate mem- ory or accumulator 1.
Fig. 4.11 (left example) shows the program of a function block without multi-in- stance capability. The example in the middle shows the same program in a function block with multi-instance capability and symbolic addressing of the local data. The example on the right shows the program with absolute addressing of the local data.