Migrating S5 OB181, LIR, TIR, and BS Instructions to S7 STEP 7
When migrating legacy SIMATIC S5 programs—particularly those originally written for the S5-135U or S5-155U chassis with CPU 928, CPU 928B, or CPU 948—engineers frequently encounter low-level S5 operations that have no direct one-to-one S7 equivalent. The instruction set OB181, LIR, TIR, and the BS operand are the most common pain points because they manipulate the S5 interpreter stack, the base address register, and absolute memory. This reference documents the exact semantics of each instruction as defined in the original S5-135U/155U operation list, maps them to the equivalent S7 STEP 7 (TIA Portal or STEP 7 V5.x) constructs, and provides STL/SCL code blocks ready for direct integration into a converted project.
1. Migration Context and Tool Chain
The official Siemens STEP 7 – From S5 to S7 manual describes a two-phase migration: (1) an automatic conversion pass that translates S5 STL/FBD into S7 STL, and (2) a manual rework phase that resolves instructions the converter cannot handle. The conversion tool is delivered as a STEP 7 optional package and produces S7 source files in STL text format that can be opened in either the classic STEP 7 V5.x SIMATIC Manager or, after re-export, in the TIA Portal.
Reference: STEP 7 – From S5 to S7 (Siemens, manual entry ID 45531547) and the SIMATIC S5 to S7 Migration / Renewal Manual.
The automatic converter flags unknown operations as syntax errors and stops the translation. OB181, LIR, TIR, and BS are listed in the converter's "manual rework required" category, along with DO DW, DI, DX, STS, DO, DO DW, ADD BF, ADD BN, ADD BT, SUB BF, SUB BN, and SUB BT (BCD floating-point operations on the S5-135U/155U).
2. S5-135U/155U Instruction Set Background
All four instructions discussed here belong to the extended operation set of the S5-135U and S5-155U. The S5-115U does not support them. They are documented in the S5-135U/155U CPU 928 / 928B / 948 – List of Operations manual and the S5-135U/155U List of Operations (Siemens manual 6ES5 998-0PR02). The CPU 928B was the first S5 CPU to add the floating-point coprocessor operations, and CPU 948 added extended bit and word addressing plus higher interrupt response. If your source program contains LIR or TIR, the original target CPU is almost certainly a 928B or 948.
3. OB181 — Test Data Block in S5
3.1 Original S5 Semantics
OB181 is a system-level organization block invoked by the S5 operating system to verify the structure of a data block. It is not a user-callable OB in the same sense as OB1; it is invoked either by a DB/DX open with structure check enabled, or by the S5 test/debugger. The OB receives the DB number in ACCU 1 and the DL/DL stack base address; it must return a status word indicating whether the DB is valid, locked, or corrupted.
On the CPU 928/928B/948, the OB181 stub occupies 32 words of code and is supplied by Siemens as part of the standard firmware. The S5 user never edits OB181 directly; the S5 converter carries the call reference into the S7 program, but the target block has no meaningful behavior because the S7 data block model is different.
3.2 S7 Replacement Strategy
The S7 data block model uses a flat memory area managed by the system; there is no need for a periodic structure test because the S7 block headers contain CRC checksums and length fields that the S7 OS validates on every download and on every cold restart (OB100). The conversion tool replaces the S5 DB n open with the S7 OPN DB [n] or OPN DI [n] instruction, and the S5 DX n open with the S7 OPN DI [n] instruction (instance DB in S7).
If the original S5 program called OB181 as a deliberate runtime check (for example, to validate a DB number received via a peripheral input), the equivalent S7 logic is:
- Read the candidate DB number into a temporary variable (DWORD).
- Use
L DB#with the ANY pointer to test the block existence via SFC 24 / SFC 6 / SFC 7. - Branch on the returned error code.
3.3 STL Replacement for Runtime DB Validation
// S7 STL – runtime DB existence check (replaces OB181 test logic)
L #iCandidateDBNum // INT in, candidate DB number (1..32767)
L 1 // lower bound
<I // ACCU2 < ACCU1 ?
JC _ERR_RANGE // -> DB number too low
L 32767
>I // ACCU2 > ACCU1 ?
JC _ERR_RANGE // -> DB number too high
// Open the DB; S7 OS will set BR if the block is loaded and valid
OPN DB [#iCandidateDBNum] // S7 raises OB121 if DB does not exist
AN OV // BR / OV check
JC _ERR_LOAD // branch if load failed
// Successful open; continue
SET
SAVE
JU _OK
_ERR_RANGE:
CLR
_ERR_LOAD:
SAVE
// ACCU1 LSB = 0 on error, = 1 on success (binary result)
_OK: NOP 0
The above replaces the S5 idiom DB n followed by an implicit OB181 invocation. The OB121 (programming error) handler installed by the user program can catch the absence of a DB and route the error to the S7 diagnostic buffer; this is the S7 analogue of the S5 "DB does not exist" signal that OB181 would have returned.
4. LIR — Load Register Indirect (S5)
4.1 Original S5 Semantics
The S5 LIR instruction reads a 16-bit word from the absolute memory address contained in ACCU 1. The address is a flat byte address that can point to any memory region: PII (process image input), PIQ (process image output), flags (M), timers (T), counters (C), data (D), or system memory (S). The loaded word is placed into ACCU 1-L (low word) while ACCU 1-H is cleared. The address in ACCU 1 is interpreted as a flat 16-bit address with the most significant bit pattern selecting the memory area according to the S5 addressing scheme:
| Address range (hex) | Memory area | S7 equivalent |
|---|---|---|
| 0000h–FFFFh (bottom 32K) | Data blocks (DB/DX) | DBB/DBW/DBD by OPN DB [n] |
| 0000h–7FFFh (PA range, bits 15=0,14=0) | Process I/O (PII / PIQ) | PIB/PIW/PID direct peripheral |
| 8000h–FFFFh (flag area, bits 15=1,14=0) | Flags (M) | MB/MW/MD |
| E000h–E7FFh | Timers (T) | T (word access requires T 0..n, LW) |
| E800h–EFFFh | Counters (C) | C (word access requires C 0..n, LW) |
| F000h–FFFFh | System memory (S) | No S7 equivalent – recreate semantically |
The S5 LIR instruction does not check that the address is in a valid range. If the address points to an unused region, the CPU returns 0000h. There is no error bit set. This silent fail behaviour is one of the most common sources of latent S5 program bugs and must be explicitly addressed when migrating.
4.2 S7 Replacement — Area-Internal Pointer
In S7 STEP 7, the equivalent operation is performed with the area-internal pointer (POINTER) or the ANY pointer together with the S7 indirect addressing modes. The most direct S7 replacement for LIR where the address lies inside a known DB is the L DBW [MD0] or L DBB [MD0] instruction with the byte offset held in a memory double word. For area-crossing access (S5 could point at M, T, C, S, or D from one instruction), the S7 replacement uses the area-crossing pointer combined with L W [AR1,P#0.0] or, in SCL, the PEEK / POKE functions from the IEC library.
4.3 STL Replacement for S5 LIR (DB area)
// S5 original
L DB 100 // load DB number into ACCU 1 (later bound to address)
LIR // load word at ACCU1 address into ACCU1-L
// (conceptual; LIR consumes the address in ACCU1 directly)
// S7 STL replacement for "load word from DB offset = MW 100"
OPN DB [MW100] // open DB whose number is in MW100
L MW 102 // load byte offset
SLD 3 // shift to pointer form (P#x.0)
LAR1 // ACCU1 -> AR1
L DBW [AR1,P#0.0] // load the word from DB[MW100] at byte offset MW102
4.4 STL Replacement for S5 LIR (cross-area)
// S7 STL – cross-area read (replaces S5 LIR when source could be M, T, C, or D)
L #iAddressWord // INT input = raw S5 address (0..65535)
L 0 // clear ACCU1-H
T #dwAddress // store as DWORD
TAR1 #arSave1 // save AR1 (S7 allows one AR1 only)
LAR1 #dwAddress // AR1 = address
L W [AR1,P#0.0] // area-crossing word read
T #wResult // result word
LAR1 #arSave1 // restore AR1
Note that the S7 L W [AR1,P#0.0] instruction will raise OB121 (programming error) if the address falls in a region that is not valid for the S7-300/400 memory map (for example, an attempt to read from an empty slot in the S5 address space). Wrap the access with an OB121 error handler if the original S5 code relied on the silent-zero fallback of LIR.
5. TIR — Transfer Register Indirect (S5)
5.1 Original S5 Semantics
TIR is the dual of LIR. It writes the contents of ACCU 1-L (a 16-bit word) to the absolute memory address contained in ACCU 1 at the time TIR executes. The standard S5 idiom is:
L W#16#0F00 // example: pointer to flag area + offset 0
L MW 200 // value to write
TIR // MW200 -> memory at ACCU1's previous address
The address in ACCU 1 is replaced by the written value; the value previously pointed to is overwritten. Like LIR, the instruction performs no range check.
5.2 S7 Replacement
The S7 equivalent uses T DBW [...], T MW [...], or the area-crossing T W [AR1,P#0.0]. For dynamic DB selection, combine OPN DB [MW_n] with a byte-offset pointer. The conversion rule is:
- Determine the target S7 area from the S5 address (use Table 1 above).
- Strip the area selector bits; the remaining low-order bits become the byte offset within that area.
- For the DB area, pre-open the DB with the desired DB number; for M, T, C, S use the corresponding S7 area directly.
- Emit the S7 store instruction with indirect addressing.
5.3 STL Replacement for S5 TIR
// S7 STL – cross-area write (replaces S5 TIR)
L #iAddressWord // S5 raw address
T #dwAddress
L #wValue // value to write
TAR1 #arSave1
LAR1 #dwAddress
T W [AR1,P#0.0]
LAR1 #arSave1
Wrap with an OB121 handler if the original S5 code expected the write to be silently ignored on invalid addresses.
6. BS — Base Address Register (ISTACK)
6.1 Original S5 Semantics
The S5 instruction-set identifier BS refers to the "Basisadressregister" (base address register). It is not a stand-alone instruction; it appears as a source operand on a load instruction to read the base address register content from the S5 interrupt stack (ISTACK). The ISTACK stores the call-context data of the currently executing block, including:
- The block header address (BA, Basisadresse).
- The block return address (BR, Ruecksprungadresse).
- The DB number and the current DL/DR pair (data word offset).
- The status word of the calling block.
The typical S5 sequence that reads BS looks like:
L BS 34 // load the BS-offset 34 from the ISTACK into ACCU 1
T MW 200
On the CPU 928/928B/948, the ISTACK occupies a fixed memory area in the system RAM, and offset 34 corresponds to the data block (DB/DX) number that was active at the point of the call. The exact mapping of offsets to ISTACK fields is CPU-specific; refer to the S5-135U/155U CPU 928B/CPU 948 – List of Operations manual, chapter "ISTACK structure".
6.2 S7 Replacement — L Stack and Local Data
The S7 operating system maintains the equivalent of the S5 ISTACK in the L stack (Lokaldaten-Stack) of each OB and the block call chain. The S7 information that maps to the S5 BS offsets is:
| S5 BS offset (CPU 928B/948) | ISTACK content | S7 equivalent |
|---|---|---|
| 0–1 | Block type / block number | Block type from OB/FB/FC header; use SFC 6 / SFC 7 |
| 2–3 | Return address (block-relative) | Not directly exposed; use SFC 35/36/37 for interrupt control |
| 34 | Active DB number (last OPN DB) | No direct instruction; query via SFC 24 "TEST_DB" or maintain own variable |
| 36 | Active DI number (last OPN DI) | Same as above; instance DB |
| 40 | Status word at call time | Read via STW / SAVE / CLR; not stack-restorable in S7 |
6.3 S7 Replacement Pattern
Because the S7 operating system does not expose the L-stack as a readable memory area, the canonical S7 replacement pattern is to capture the equivalent context at the time the block is called and pass it as IN/IN_OUT parameters on the FB/FC interface. The S7 FB becomes self-contained and the dependency on stack state is removed.
// S7 FB interface (replaces BS-offset 34 reads inside an FB/FC)
FUNCTION_BLOCK FB_DBContext
VAR_INPUT
iCallSource : INT; // caller identifier (0=OB1, 1=OB35, etc.)
END_VAR
VAR
sDiag : STRUCT
dbNum : INT; // mirrors active DB at call
diNum : INT;
stw : WORD; // status word at call
END_STRUCT;
END_VAR
BEGIN
// Save the caller's DB context into instance fields
sDiag.stw := STW; // current status word
sDiag.dbNum := DB_NUMBER; // requires SFC 24 in SCL
// ...
END_FUNCTION_BLOCK
To make the migration auditable, store the BS-replacement fields in the FB's instance DB; this keeps the diagnostic data available to HMI / WinCC via the standard tag list. If the original S5 program was reading BS for error reporting (e.g., before transitioning to STOP), the S7 equivalent is to populate the OB1x error OBs (OB80 through OB87) with the equivalent SFC 6 / SFC 7 reads of the local-data area at the time of the fault.
7. Step-by-Step Migration Procedure
7.1 Prerequisites
- STEP 7 V5.5 SP4 or later (or TIA Portal V15.1+ for the re-export path).
- The official "S5 to S7 Converter" optional package installed under SIMATIC Manager.
- Manual "S5-135U/155U CPU 928/928B/948 List of Operations" for reference.
7.2 Procedure
- Identify the original S5 CPU. Open the S5 program header in STEP 5 and confirm the CPU model. Record the firmware version if the hardware is still in operation.
- Run the S5-to-S7 converter. From SIMATIC Manager, choose Options > S5 to S7 Converter. Select the source S5 program, the target S7 project, and the mapping rules. Click "Convert". The tool produces a S7 project with a conversion report listing all operations that require manual rework.
-
Open the conversion report. The report file
S5_to_S7.LOGlists every line that failed automatic conversion. LocateOB181,LIR,TIR, andBSreferences; they will be flagged asNOT_CONVERTEDwith the source line number. -
Replace
OB181calls. For each call to OB181, decide whether the S5 program used the OB as a runtime DB test or as a debugging hook. In runtime tests, replace with the STL pattern in section 3.3. In debug-only references, simply delete the call; the S7 OS validates DBs at download time. -
Replace
LIRandTIRinstructions. For each occurrence, classify the target S5 address by the table in section 4.1. Apply the STL pattern from section 4.4 (cross-area) or section 4.3 (DB-internal). Update the surrounding logic to clear the result word before the call (the S5LIRalways returned a word, but if the load failed the ACCU1-L was 0000h — S7 will leave the prior value untouched on an OB121). -
Replace
BSreads. For eachL BS nninstruction, identify which ISTACK offset is being read. Substitute the corresponding FB instance field or a local temporary initialized at block entry. If the read was part of an error handler, route the diagnostic data to the appropriate OB80–OB87. - Re-compile in STEP 7. Use the "Check block consistency" tool to verify all blocks compile. The S7 compiler will flag any unresolved references with line numbers.
- Download to the S7 CPU. Use a S7-300 CPU 315-2 PN/DP, S7-400, or ET 200S with adequate work memory. Confirm the CPU is in STOP before download.
- Verify the migration (see section 9).
8. Worked Example — Migrating FB175 Caller to OB181
The original S5 program (as reported in the field report) contained the call pattern:
// S5 source (illustrative)
L DB 100
LIR // load word from absolute address in ACCU1
T MW 202
L DB 200
TIR // write MW204 to absolute address in ACCU1
L BS 34 // read active DB from ISTACK
T MW 206
SPA OB 181 // call system OB to validate DB structure
After conversion, the S7 STL equivalent is:
// S7 STL — migrated body of the original S5 routine
OPN DB 100
L DBB 0 // equivalent of LIR at offset 0
T MB 203
OPN DB 200
L MW 204
T DBB 0 // equivalent of TIR at offset 0
CALL SFC 24 // TEST_DB – equivalent of OB181 runtime check
L DB# 200
T MW 206 // store returned DB number
L W#16#0
==I // TEST_DB returns "DB does not exist" = 0
JC ERR_DB200
// ... success path ...
ERR_DB200:
// S7: raise OB121 via "L DW#16#0 / T DBW 0" on a non-existent DB
L DB# 32766
OPN DB [MW206] // forces OB121 if DB# is not loaded
9. Verification
Verification of a migrated S5/S7 program combines a static analysis pass, a dynamic test pass on the target CPU, and a long-duration soak test to expose the S5 LIR/TIR silent-zero cases that no off-line tool can detect.
9.1 Static Analysis Checklist
- All
LIR/TIRsites have a corresponding S7 cross-area or DB-internal replacement. - No call to OB181 remains in the S7 source (other than the documented runtime pattern using SFC 24).
- No
L BS nninstructions remain; equivalent state is stored in the FB instance DB. - OB121, OB80, OB85, OB121, and OB122 error handlers are installed in the S7 program.
9.2 Dynamic Test on the S7 CPU
- Force the CPU to RUN-P (run with programming device attached). Open the S7 diagnostic buffer and confirm no OB80–OB87 entries appear after a 10-minute idle period.
- Use a watch table to force the DB number used in the runtime-DB test to 0 and to 32767; verify the SFC 24 returns the expected error code and the OB121 handler routes the fault to the HMI.
- For each
LIR/TIRreplacement, force the address high word to a non-existent area selector and confirm the OB121 path is exercised. - Compare the cyclic I/O image against the S5 program reference trace for at least 1000 scans.
9.3 Soak Test
Run the migrated program for a minimum of 24 hours with the original S5 test vectors replayed at the digital and analog I/O level. Capture every OB entry and every PLC stop event. The acceptance threshold is zero unjustified OB entries (OB1x raised for reasons that the original S5 program did not produce).
10. Common Pitfalls and Edge Cases
10.1 The Silent Zero
S5 LIR returned 0000h on an out-of-range address without setting any status flag. S7 raises OB121 on a similar access. If the original S5 program depended on the silent zero, the S7 program must explicitly handle the OB121. A common bug is a LIR whose address pointer was momentarily uninitialized during startup; the S5 program would read 0, the S7 program will raise OB121 and the CPU will go to STOP if OB121 is not loaded.
10.2 Cross-Area Pointer Truncation
S5 LIR/TIR operated on a 16-bit address. S7 cross-area instructions use a 32-bit pointer (DWORD). When migrating, the 16-bit S5 address must be sign-extended or zero-extended to 32 bits depending on whether the original S5 program treated the top bit as a flag-area selector. Inspect the original S5 source for any conditional logic on bit 15 of the address; if present, the S7 code must reproduce that conditional bit-test.
10.3 BS Offset 34 Active DB
The S5 BS offset 34 reads the active DB number. In S7, after an OPN DB [MW_n], the S7 OS internally tracks the active DB but does not expose it as a readable register. Two practical approaches: (a) maintain a shadow variable updated every time OPN DB [...] is executed, or (b) use SFC 24 (TEST_DB) to look up a specific DB number. Approach (a) is faster, approach (b) is more robust against missed updates.
10.4 L Stack Depth in S7
The S7 L stack is sized per OB; an OB that calls many nested FBs may run out of L stack if the S5 program used BS reads at deep call depths. The S7 configuration tool warns about L stack overflow at the block compile step. Increase the L stack size in HW Config > CPU Properties > Local Data, or flatten the call chain.
10.5 OB181 Default Behaviour in S5
If the original S5 program did not load a custom OB181 and relied on the Siemens default, no further action is required; the default behaviour is to validate the DB and return without side-effect, which is now provided automatically by the S7 OS. If the original S5 program overrode OB181 with custom code, the S7 replacement must reproduce the custom logic in a user-installable FC and call it explicitly.
11. Replacement CPU Selection
The S5-135U/155U program target was almost always a CPU 928, 928B, or 948. The recommended S7 replacements are:
| S5 CPU | Recommended S7-300 CPU | Recommended S7-400 CPU | Notes |
|---|---|---|---|
| CPU 928 | CPU 315-2 PN/DP (6ES7315-2EH14) | CPU 412-2 PN (6ES7412-2EK06) | Standard scan time, 256 KB work memory |
| CPU 928B | CPU 317-2 PN/DP (6ES7317-2EK14) | CPU 414-3 PN/DP (6ES7414-3EM06) | Floating-point heavy, 1 MB work memory |
| CPU 948 | CPU 319-3 PN/DP (6ES7318-3EL01) | CPU 416-3 PN/DP (6ES7416-3ES06) | Bit-heavy, 2 MB work memory, multi-rack |
For the I/O side, the S5-135U/155U rack was typically replaced with an ET 200S or ET 200SP distributed I/O station; the S5 IM 300/IM 310 interface modules are replaced with PROFIBUS or PROFINET masters. The Siemens migration manual "SIMATIC S5 to S7 Renewal" (see the additional research) provides rack-by-rack replacement tables.
12. Standards and References
- Siemens – STEP 7, From S5 to S7 (Entry ID 45531547)
- Siemens – SIMATIC S5 to S7 Migration / Renewal Manual
- Siemens – S5-135U/155U CPU 928 / 928B / 948 List of Operations (manual 6ES5 998-0PR02)
- Siemens – STEP 7 V5.5 Reference Manual, S7-300/400 System Software
What does the S5 instruction LIR do, and what is its S7 STEP 7 equivalent?
The S5 LIR instruction loads a 16-bit word from the absolute memory address contained in ACCU 1. In S7 STEP 7, the equivalent is a cross-area word read using a pointer in AR1, e.g. L W [AR1,P#0.0] after loading the byte offset into AR1. For DB-internal access, use L DBW [MD_offset] inside an opened DB.
How do I replace the S5 OB181 "Test Data Block" call in a S7 program?
For runtime DB validation, replace OB181 with SFC 24 (TEST_DB), which returns a status word indicating whether the DB is loaded, valid, or absent. If the S5 program invoked OB181 only for the S5 debugger, delete the call; the S7 OS validates DBs at download time. Wrap the access with an OB121 handler if the original code relied on the S5 silent-zero fallback.
What is the S5 BS operand and how do I migrate L BS 34 to S7?
BS reads a field from the S5 interrupt stack (ISTACK). BS offset 34 holds the active DB number. The S7 operating system does not expose the L stack as a readable memory area; maintain a shadow variable updated on every OPN DB, or query the DB number via SFC 24 (TEST_DB). Store the value in the FB instance DB for HMI diagnostics.
Why does my migrated S7 program raise OB121 on addresses the S5 program accepted?
S5 LIR and TIR return 0 silently on out-of-range addresses. S7 raises OB121 (programming error) on out-of-range cross-area access. Install an OB121 error handler that sets a diagnostic flag and continues, matching the S5 silent-zero behaviour. Without OB121 the CPU will go to STOP on the first bad access.
Which Siemens S7 CPU should I use to replace a S5-135U/155U CPU 928B?
For a S5-135U/155U CPU 928B replacement, use a SIMATIC S7-300 CPU 317-2 PN/DP (6ES7317-2EK14) for compact applications, or a S7-400 CPU 414-3 PN/DP (6ES7414-3EM06) for rack-distributed plants. Verify the work-memory footprint of the migrated S7 program does not exceed the CPU's load memory and work memory specifications.