Problem Statement: Shared DB Values That Refuse to Stay
A STEP 7 user program with several hundred function blocks, instance DBs, and a handful of shared (global) DBs holds the recipe, setpoints, and mode bits that the rest of the machine reads. From time to time one particular shared DB refuses to hold whatever an engineer writes into it: the value stays correct for roughly one second and is then overwritten by something the engineer cannot identify. STEP 7's cross-reference (Querverweis / Reference Data) lists every direct symbolic access but reports nothing that touches the byte in question, even after refreshing the reference data and rebuilding the S7 program.
The behavior is the textbook signature of an indirect write. An indirect address in STEP 7 is built dynamically at runtime by an arithmetic instruction, by loading a pointer into one of the address registers (AR1, AR2), or by passing a pointer through an FB/FC parameter. Because the operand is computed at execution time, the offline cross-reference cannot know which DB, byte, or bit is actually being touched and silently excludes it from the symbol table. The same blind spot hides any data block opened with OPN DB [AR1,P#0.0] or AUF DB [AR2,P#0.0], any mass copy with SFC20 BLKMOV, any write issued by an HMI tag, any put/write issued by a peer CPU on PROFIBUS or PROFINET, and any broadcast executed through a Global Data (GD) circle.
This reference walks through every category of indirect write that touches an S7-300 / S7-400 shared DB, lists the instruction mnemonics and SFCs/SFBs that produce them, and gives a deterministic diagnostic workflow that closes the search without opening two hundred blocks by hand. The workflow is valid for STEP 7 V5.5, V5.6, and V5.7 (the latest classic STEP 7 release) on S7-300 (CPU 31x, CPU 319) and S7-400 (CPU 41x, CPU 416, CPU 417). TIA Portal equivalents are called out where the menu paths or operands differ.
Why the Cross-Reference Cannot See Indirect Writes
The Reference Data editor in STEP 7 V5.x is generated offline at compile time. It scans the STL or LAD/FBD source for explicit operands such as DB100.DBX0.0, L "speed_setpoint", or U M 12.3. Whenever the operand contains a pointer or an address register, the tool cannot resolve the concrete destination and drops the entry silently.
The following constructs, all common in machine control code, are invisible to the offline cross-reference:
- Memory-indirect, register-indirect, and area-crossing STL commands.
- Mass data movement with
SFC20 BLKMOV,SFC21 FILL,SFC75 SET_MASK / SET / RESET, andSFC81 UBLKMOV. - Read/write SFCs that take an
ANYpointer computed in the program (SFC15 WRITE,SFC22 CREAT_DB, the S7-communication SFBs). - S7 communication partners writing the DB over the backplane, PROFIBUS-DP, or PROFINET IO using
PUT/WRITESFBs on a peer CPU. - GD (Global Data) circles configured in NetPro.
- HMI variables bound to the same DB through WinCC flexible, ProTool, TIA Portal HMI, or WinCC V7.
- OPC DA / OPC UA servers (Simatic Net, Softing, Kepware) with the S7-300/400 as their source.
- S7-PDIAG, S7-GRAPH, S7-HiGraph, and S7-SCL blocks that internally generate indirect access.
- Diagnostic and block-status SFCs that write into the diagnostic buffer of the same DB if the project maps the buffer to a user DB.
Each category must be hunted separately. The workflow below gives the same execution order a maintenance engineer should follow: register-level STL, source grep, communication partners, system functions, HMI, GD, and finally the diagnostic buffer.
Indirect Addressing Modes in STEP 7 STL
STEP 7 STL supports three classes of indirect addressing on the S7-300 / S7-400. Every one of them resolves the destination at runtime and therefore defeats the offline cross-reference. The S7-1200/S7-1500 use the same syntax in STL but the operand field rules differ; TIA Portal hides STL behind the compiler so indirect writes are seen as %DB*.%DBW* expressions in the SCL source.
| Class | Syntax example | Meaning | Cross-ref visible? |
|---|---|---|---|
| Memory-indirect, area-internal | A DBX[MD10] |
Byte/bit offset inside current DB computed from MD10 | No |
| Memory-indirect, area-crossing |
A DBX[MD10] after OPN DB [AR1,P#0.0]
|
Address register points to DB number, MD10 is offset | No |
| Register-indirect, area-internal | A DBX[AR1,P#0.0] |
AR1 holds offset inside current DB | No |
| Register-indirect, area-crossing | A D[AR1,P#10.0] |
AR1 is 32-bit pointer: bits 0..23 = byte/bit offset, bits 24..31 = area ID (B/M/D/T/Z) | No |
| Parameter type (POINTER, ANY in FC/FB; VARIANT in SCL) | // POINTER param |
Pointer passed into block | Only the parameter signature, never the resolved DB |
The area-crossing format is the most dangerous. The destination pointer is loaded into one of the address registers, and the instruction itself does not name the DB. The compiler and the cross-reference treat such an instruction as operand-less because the operand is built inside the register.
Typical STL that hides a write:
// Open DB by number loaded from somewhere dynamic
L #i_db_no // INT, e.g. from recipe block
T LW 0
OPN DB [LW 0] // DB number comes from a variable
// Build destination pointer in AR1
L #i_offset // DINT offset inside DB
SLD 3 // multiply by 8 to make bit offset
L P#DBX 0.0 // area ID 0x84 = DB byte
OD
LAR1
// Write the value
L #i_value
T DBB [AR1,P#0.0]
The cross-reference will see OPN DB [LW 0] as a "DB operand without symbol" line and will not connect it to the user-defined shared DB that contains the variable the engineer is trying to protect. The T DBB [AR1,P#0.0] line is reported as touching an unknown memory area and is also dropped from the useful output.
Common indirect write idioms in SCL:
// SCL example 1: array element write
FOR i := 1 TO 100 DO
"dbRecipe".array[i] := #src_value;
END_FOR;
// SCL example 2: AT view over a larger array
FUNCTION_BLOCK FB_Touch
VAR
arr : ARRAY[0..99] OF BYTE;
view : AT arr : ARRAY[0..99] OF BOOL; // bit view
END_VAR
view[#index] := #state;
// SCL example 3: PEEK/POKE word addressing
FUNCTION_WORD := PEEK(area := 16#84, dbNo := #dbNo, byteOffset := #off);
POKE(area := 16#84, dbNo := #dbNo, byteOffset := #off, value := #v);
Right-click the SCL block in SIMATIC Manager and choose Generate STL source. The exported STL contains the inline access patterns LAR1, +AR1, T DBB[AR1,P#0.0], and UC SFC 20 that the grep step below will find.
Diagnostic Step 1: Online "Go to Location" With Overlapping Access
STEP 7 has a built-in trick that the offline cross-reference cannot replicate: the online "Go to Location" function works on the live CPU, jumps to the call site that last touched the address, and follows an indirect access as long as Overlapping access to memory areas is enabled. This is the fastest single-step diagnostic if the engineer can get the project online and force the offending write to repeat.
- Open the program editor (STL or LAD/FBD) for the block that contains the address of interest.
- Select Options > Customize > STL (or LAD/FBD) tab and tick Overlapping access to memory areas. Equivalent path in STEP 7 V5.7: Options > Settings > PC Internal > STL editor > Operand field overlap. In TIA Portal the corresponding setting is Tools > Options > PLC programming > STL > Operand field overlap.
- Place the cursor on the suspected operand (e.g.
DB100.DBX4.0). Right-click and choose Go to > Location (in the German UI: Gehe zu > Verwendungsstelle). - STEP 7 jumps to the next network that touches the address. For indirect accesses the dialog reports the address where the operand could be in the byte/bit overlap window. Confirm the open network and repeat from the new location.
- If the cursor lands on
OPN DB [...]or on a register-indirect instruction, the tool can still resolve the symbolic location if the pointer source has been monitored online. Open a Monitor/Modify table on AR1 / AR2 and step the program in single-scan mode (PLC > Operating Mode > Single Scan) to catch the value at the moment of the write. - Repeat for every overlapping operand the editor proposes. The byte/bit overlap window can offer four or five possible destinations; cross-reference the destinations against the variable that is being overwritten to narrow the search.
Limitations: "Go to Location" follows one step at a time. It cannot trace the entire chain that leads to AR1 being loaded. For multi-hop indirect chains it must be combined with a breakpoint on the instruction that writes the address register (see Step 6).
DB100.DBX4.0 can overlap with DB100.DBB4, DB100.DBW4, and DB100.DBD4, but not with DB100.DBB3. Set the search to DBW first to widen the overlap to byte and word matches.Diagnostic Step 2: Export Sources and Grep the STL
When the project is offline only, or when there are dozens of blocks to scan, exporting the entire program to one or more STL source files and searching them with a plain text editor is the most reliable technique. A single STL file condenses every FB, FC, OB, DB, and UDT into one searchable document, and the indirect-addressing mnemonics are rare enough that a few grep patterns finish the search in seconds.
- In the SIMATIC Manager right-click the Blocks container and choose Generate Source. Pick a name such as
ALL_BLOCKS.src. Accept the default option to generate all blocks. - STEP 7 compiles the source. Re-edit any blocks that fail to compile because they contain SCL or GRAPH code; the export will skip them with a warning. For SCL blocks, right-click the block and choose Generate source > STL source to obtain a view of the indirect accesses the SCL compiler introduced.
- Open the resulting
.srcfile in Notepad++, UltraEdit, VS Code, orless. Save a copy withCR/LFstripped so thatgrep -nmatches work cleanly across line continuations. - Run a battery of pattern searches against the file. Use case-insensitive matching and exclude comment lines with
grep -vE '^\s*//'.
Recommended search patterns (run each one separately):
grep -niE 'OPN[[:space:]]+DB[[:space:]]*\[' all_blocks.src
grep -niE 'AUF[[:space:]]+DB[[:space:]]*\[' all_blocks.src # German UI
grep -niE 'LAR[12]|TAR[12]|\+AR[12]|-AR[12]' all_blocks.src
grep -niE 'DBB?[[:space:]]*\[|DBW?[[:space:]]*\[|DBD?[[:space:]]*\[' all_blocks.src
grep -niE 'BLKMOV|FILL|UBLKMOV' all_blocks.src
grep -niE 'SFC[[:space:]]*(15|20|21|22|23|75|81)\b' all_blocks.src
grep -niE 'SFB?[[:space:]]*(8|9|12|13|14|15|16|18|19)\b' all_blocks.src
grep -niE 'CALL[[:space:]]+"?(PUT|GET|USEND|URCV|BSEND|BRCV)\b' all_blocks.src
grep -niE 'P#\s*DB[XBWD]|P#\s*D\s+B\s*\d' all_blocks.src
grep -niE '\bPEEK\b|\bPOKE\b' all_blocks.src # SCL peek/poke
grep -niE 'CREAT_DB|DEL_DB' all_blocks.src
grep -niE 'DB_ANY|ANY_POINTER|POINTER' all_blocks.src
grep -niE 'TCI[A-Z]?|DPRD|DPWR' all_blocks.src # DP read/write
Each match line lists the block name and the network number. Open that block in the editor and inspect the surrounding network. If the offset inside the pointer matches the byte/bit that the shared DB is being written to, you have found the writer. Cross-check the network against the call stack captured in single-scan mode (Step 1) to confirm.
t#db_xyz, #temp_dword, and #_index_. Any t#db_xyz := value statement where the left-hand side is computed from an index variable, an AT view on a larger variable, or a slice expression ("db"."struct"."arr"[i].field) is an indirect write to a shared DB. Repeat the grep on the generated STL by right-clicking the SCL block and choosing Generate STL source.Diagnostic Step 3: PUT / GET, USEND / URCV, and S7 Communication
If the shared DB is part of a multi-CPU setup, an S7-1500/1200 peer, or a third-party controller talking to the S7-300/400 over S7 communication, the writer is most likely an external station that calls PUT (write to this CPU) or GET (read from this CPU). Neither call shows up in the user program of the target CPU because the write is performed by the operating system of the communication processor (CP) or the PN interface once the call has been authenticated.
- Open NetPro. Inspect every S7 connection terminating on the CPU. Note the connection partner, the connection ID, and the configured Active connection establishment flag.
- For each connection, open the partner's Properties and check whether the partner's Object list for PUT contains the affected DB number. In NetPro right-click the connection, select Object list, and see exactly which DBs are reachable. Restrict the list to the DBs the partner actually needs.
- On the receiving CPU, monitor the operating mode. A diagnostic buffer entry
STOP due to communication errorcombined with event ID0x13xxindicates a malformed PUT request. Event ID0x35xxsignals an unauthorized write attempt that was rejected by the protection level. - If the program includes calls to
SFB14 GET,SFB15 PUT,SFB8 USEND,SFB9 URCV,SFB12 BSEND, orSFB13 BRCVinOB1orOB35, the receiving side of these blocks also issues a write to the SDO/SDB area when the data block pointer argument names the shared DB. Add those SFBs to the grep list of Step 2. - For PROFINET IO / PROFIBUS-DP slaves that act as IO controllers (ET 200S with PN interface, SINAMICS drives with PN, ET 200pro), inspect the slave's slot configuration for any acyclic record writes. The CPU logs acyclic writes through the diagnostic buffer with event IDs
0x0E01and0x0E02. - For S7 routing through a CP, open the CP's online diagnostics (right-click the CP in HW Config > Online > Diagnostics) and check the connection list. Routed connections can write to the CPU without appearing in the local connection table.
Diagnostic Step 4: SFC20 BLKMOV, SFC21 FILL, and System Functions
SFC20 BLKMOV and SFC21 FILL copy or fill a region described by an ANY pointer. Because the source or destination ANY is computed at runtime from variables, the cross-reference reports the call as "block without parameter connection" and never connects it to the destination DB.
- Grep for
CALL "BLKMOV",CALL SFC 20, or theSFC20token (already covered by the pattern above). - For each match, read the source and destination
ANYarguments. The ANY pointer layout in STEP 7 is 10 bytes:
+------+------+------+------+------+------+------+------+------+------+
| 10h | 00h | typ | rep. | byte/bit offset (32-bit pointer) |
+------+------+------+------+------+------+------+------+------+------+
byte 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte 6 byte 7 byte 8 byte 9
The data-type byte (byte 2) determines the operand: B#16#10 = DB byte, B#16#12 = DB word, B#16#14 = DB double word, B#16#20 = bit (Boolean), B#16#04 = word outside DB. Bytes 4-5 are the repetition count (length in bits for bit-typed ANY, in units of the type for byte/word/double word). Bytes 6-9 are the byte/bit offset within the operand area.
- Run the program with a watch on the ANY pointer just before the call. STEP 7 can display the byte/bit representation of the ANY: open the variable in the Monitor/Modify table as
ABY(any binary) and check the data-type nibble. Confirm the byte 2 is0x10..0x14, the length matches the variable the engineer is protecting, and the offset matches the byte/bit range being overwritten. - Other SFCs that hide writes:
-
SFC15 WRITE— writes a row of data to a peer DP slave. Watch for an indirect destination pointer. -
SFC75 SET_MASK/SET/RESET/RESET_BF— operate on a single bit or on a bit array of an input/output/process-image area. If the pointer points at the process-image output of a module that is also being read by the program, the value can flip. -
SFC81 UBLKMOV— unaligned block move with the same ANY-pointer trap. -
SFC22 CREAT_DBandSFC23 DEL_DB— dynamic DB creation. The created DB can be at the same number as the shared DB you are protecting, depending on the maximum DB number configured in HW Config. -
SFC43 RE_TRIGRandSFC46 STP— STOP/RUN transitions can also be triggered by communication, but the symptom here is value-flip, not mode change. -
SFC51 RDSYSST— reads a system state list. The output ANY can be redirected to a user DB and overwrite its first N bytes if the length is wrong.
SFC22 can steal the DB number of a shared DB if the project's Maximum DB number is greater than the highest numbered shared DB and the runtime permits overlapping numbering. Symptom: the program that "used to work" now gets writes from a newly created DB because both share the same slot in the DB register. Open HW Config, set Maximum DB number = (highest numbered shared DB) and reload the CPU.Diagnostic Step 5: HMI, WinCC, ProTool, and OPC Tag Bindings
HMI software writes to DBs through the S7 communication channel the same way a peer CPU does, but the tag definition lives in a separate project. The HMI is therefore invisible to the STEP 7 cross-reference by design. Identify candidates as follows:
- List every HMI panel, WinCC station, OPC server, and S7-PM project that points to the same CPU. The fastest check is to open NetPro and look at the connections terminating on the CPU; HMIs appear with connection type S7-HMI.
- For each HMI project, open the tag editor and filter on the affected DB number (e.g.
DB100). Tags whose name ends with_SP,_CMD,_W, or_Mare typically writeable. Note the tag names and the polling cycle. - In the HMI screens, search for the tag name. Almost every writable tag is connected to an Output field, a Slider, a Button, or a Recipe view. Open the screen and check the event configuration: a value entered in an I/O field is written immediately on change, while a slider writes on release. The one-second interval in the original symptom is consistent with a recipe list that re-applies its value on every cycle, with a PLC job from WinCC flexible's PlcJob, or with a comfort panel's 1-second cyclic write of a status tag that the HMI project bound to a writeable address by mistake.
- For WinCC V7, the relevant project is the Tag Management > SIMATIC S7 PROTOCOL SUITE > TCP/IP or Industrial Ethernet connection. Right-click the connection and choose Tags; filter on the DB number.
- For TIA Portal HMI tags (Comfort Panels, WinCC Unified), the tag configuration is inside the TIA Portal project itself and the relationship between the HMI tag and the DB is visible from the Connections view. Add the project to the TIA Portal multi-user server to inspect the binding.
- OPC DA and OPC UA servers (Simatic Net, Softing, Kepware) hold the configuration in a separate file. Disable the OPC server temporarily; if the DB value stabilises, the OPC tag is the writer. Replace the tag with a read-only tag or restrict the OPC group to read access.
- For ProTool / WinCC flexible projects, the connection configuration lives in Project > Connections. The tag list under Tags shows the DB address and access mode (read-only / read-write).
SetTag, SetTagRaw, SetTagBit, or SetProperty in the VBScript or C action sections.Diagnostic Step 6: Global Data, CPs, and the Diagnostic Buffer
After all of the above have been checked, the residual cases are listed below. Each one is easy to miss because it does not produce a write in the user program.
- Global Data (GD) circles configured with the CPU as receiver. Each GD row in NetPro contains the source byte/bit and the destination byte/bit. Open NetPro, double-click the GD table, and inspect every row whose destination is the shared DB in question. Disable the GD row temporarily by removing the receiver CPU from the circle; if the value now holds, the GD row was the writer.
- CP routing through a CP (CP 343-1, CP 443-1 Advanced, CP 343-1 Lean). Routing partners can write into the CPU via the CP without a NetPro-visible S7 connection. Check the CP's connection list by opening CP Diagnostics in the online view.
-
System function error callbacks that write the error code into a user DB.
SFC36 / SFC37(mask / unmask events),SFC39 / SFC40(OB priority), andSFC41 / SFC42(delay / interrupt) all write into OB100 / OB121 / OB122 if those OBs are not loaded. Verify all OBs referenced by the program are loaded on the CPU. - Diagnostic buffer entries that reveal a cyclic write. Open PLC > Diagnostics/Setting > Diagnostic Buffer and look for repeated entries with the same time stamp pattern. Event IDs of interest:
| Event ID | Meaning | Action |
|---|---|---|
| 0x13xx | Malformed PUT request from partner | Restrict the object list on the partner's connection |
| 0x35xx | Unauthorized write attempt rejected by protection level | Confirm CPU protection level; identify the source from the partner's IP |
| 0x39xx | Module / submodule failed | Check the slot for a removed module that the program still references |
| 0x4300 | I/O access error when reading | Indirect read of a non-existent slot — set a breakpoint |
| 0x4543 | STOP because of programming error (OB not loaded) | Load the missing OB and re-test |
| 0x0E01 / 0x0E02 | Acyclic record write/read on a PN/DP slave | Inspect the slave's slot configuration |
| 0x38xx | Communication partner disconnected | Identify the partner and check whether its connection is needed |
If the diagnostic buffer is empty and the value still flips, set a breakpoint on every indirect instruction in the suspect block. In the editor, right-click the STL line and choose Set Breakpoint. Force the CPU into Single Scan mode (PLC > Operating Mode > Single Scan) and step through the OB1 cycle. The breakpoint halts execution on the indirect write, and the call stack in the online view shows the path from the OB that triggered it.
For long-running cycles, set the breakpoint to Trigger on condition with a comparison on the value being overwritten. For example: DB100.DBW 4 <> 0. The CPU only halts when the condition becomes true, eliminating the need for visual inspection of the value during the single-scan.
Search Pattern Reference Table and Verification Procedure
Combine the steps above with the patterns in the table below. Each pattern points at a category of writer and lists the block type to inspect once the match is found.
| Pattern (regex / token) | Writer category | Block to inspect |
|---|---|---|
OPN DB [, AUF DB [
|
Indirect DB open inside FB/FC | All FBs/FCs in the S7 program |
LAR1, LAR2, +AR1, TAR1
|
Address-register based access | Any block that handles arrays / loops |
DBB[AR, DBW[AR, DBD[AR
|
Register-indirect DB access | Any block that handles array element write |
CALL "BLKMOV", CALL SFC 20
|
Mass copy | Any block that initialises or refreshes a structure |
CALL "FILL", CALL SFC 21
|
Mass fill | Block that zeroes or initialises the DB at startup |
CALL "PUT", SFB15, FB15
|
Peer CPU writing this CPU | NetPro object list, peer CPU's blocks |
CALL "GET", SFB14, FB14
|
Peer CPU reading this CPU (response is local) | Peer CPU's blocks, but verify DB has not been written via PUT side |
CALL "USEND" / URCV / BSEND / BRCV
|
S7 communication send/receive | Block that performs acyclic or cyclic send |
P#DBX, P#DBB in code (not in FB header) |
Static ANY that has been built dynamically | Block where ANY is built from input parameters |
PEEK, POKE in SCL |
SCL peek/poke word-addressed access | SCL source of the block (right-click > STL source) |
| HMI tag linked to the DB | HMI / WinCC / OPC write | HMI project or OPC configuration |
| GD row destination = DB byte | Global Data | NetPro > GD table |
SFC22 CREAT_DB with dynamic number |
Dynamic DB overlaps the static shared DB | OB100 / OB1 startup blocks |
SFC15 WRITE with dynamic ANY |
DP/PN acyclic record write | Block that issues the write |
TCI (TCON / TDISCON / TSEND / TRCV) |
Open user communication over TCP | Block that handles the TCP send/receive |
Verification procedure: once a candidate writer has been identified, force it offline and observe the shared DB. Concretely:
- In NetPro, temporarily delete the GD row (or comment it out) and download the project. If the DB value holds, GD is the writer.
- If the suspect is an HMI tag, set the tag's access to read-only in the HMI project and download to the panel. If the DB value holds, the HMI tag was the writer.
- If the suspect is an SFC call inside the CPU program, replace the SFC with
NOP 0and download. If the DB value holds, the SFC was the writer. - For peer CPU PUT, disconnect the network cable or block the connection ID in NetPro (set connection status to disabled, then download). If the DB value holds, the peer is the writer.
- For OPC, stop the OPC server service. If the DB value holds, the OPC tag was the writer. Tighten the OPC group to read access.
- For SFC22 dynamic DB creation, temporarily set Maximum DB number in HW Config to the highest numbered shared DB and reload. If the DB value holds, the dynamic DB was overlapping.
Restore the configuration once the writer is documented and a controlled write path is in place. Add a comment in the shared DB header that lists every indirect writer and the protective pattern used to defend the value. Update the project's Symbol Table and Reference Data comment column with a one-line reference to the documentation block (e.g. // see FB123 "TouchGuard" for write protection).
Preventive pattern for the protected variable:
// FB "TouchGuard" — denies indirect writes to a single DB byte
FUNCTION_BLOCK FB_TouchGuard
VAR
i_db : INT; // protected DB number
i_byte : INT; // protected byte offset
i_value: BYTE; // last allowed value (set from HMI once)
END_VAR
BEGIN
// Read the protected byte once per cycle
IF (#i_db > 0) AND (#i_byte > 0) THEN
// Open the DB and read; if different from last allowed value, restore.
...
END_IF;
END_FUNCTION_BLOCK
Pair this with a read-only protection level on the HMI tag and a restricted object list on every PUT connection. The combination closes the indirect-write loop in three independent layers.
Frequently Asked Questions
Why does my offline cross-reference (Querverweis) show nothing writing to a DB byte even though the value keeps changing online?
The cross-reference is computed at compile time from explicit operands in the source. STL constructs that resolve the destination at runtime — OPN DB [...], LAR1/LAR2, DBB[AR1,P#0.0], CALL SFC20 BLKMOV, peer PUT requests, HMI tag writes, and GD rows — do not appear in the offline output. Use the online "Go to Location" function with overlapping access enabled, or grep the generated STL source for the patterns listed above.
What is the difference between memory-indirect and register-indirect addressing in STEP 7 STL?
Memory-indirect uses a double word in the bit-addressed memory (M, D, L) as the offset or pointer. Register-indirect uses address register AR1 or AR2. Area-internal variants stay inside the same operand area (DB or M). Area-crossing variants carry both the area ID and the byte offset in the register and can switch between DB/M/I/Q in a single instruction. Only the area-crossing register-indirect form can address any DB byte from any block without re-opening the DB.
How can I prevent an external partner CPU from overwriting my shared DB through PUT?
Open the S7 connection in NetPro, clear the Object list for PUT entries that point at the protected DB, and set the CPU's Protection level to Write-protection or Write/read-protection with password. Also confirm the CP or PN interface firmware is current so that the PUT-rejection patch is active. Event ID 0x35xx in the diagnostic buffer confirms that an unauthorized PUT was rejected.
Can an HMI panel write to a shared DB through tags that the program does not name explicitly?
Yes. WinCC flexible, TIA Portal HMI, WinCC V7, and OPC DA/UA servers all bind to DB bytes by address and write whenever the operator changes a value or a script forces an update. Disable the HMI or OPC server, or set the tag access to read-only in the HMI project; if the value now holds, the HMI was the writer. Restrict write access through the panel's user administration to prevent the same issue from recurring.
Which STEP 7 diagnostic tool tells me whether SFC20 BLKMOV is the source of the overwrite?
Grep the generated STL source for CALL "BLKMOV", set a breakpoint on the BLKMOV call, open a Monitor/Modify table on the destination ANY pointer, and step the OB1 cycle. If the breakpoint halts on every write of the protected byte, BLKMOV is the writer. Replace the BLKMOV with a guarded copy that only runs when an enable bit is set, or refactor the call into a fixed-offset assignment.