Overview: AWL/STL Machine Code in the Simatic S7
AWL (Anweisungsliste) — marketed internationally as STL (Statement List) — is the textual low-level language for the Simatic S7-300 and S7-400 families. The user-visible mnemonics (U, O, L, T, SET, L MB 1, etc.) are assembled by STEP 7 into a compact binary image that the CPU firmware interprets at scan-time. This binary image is sometimes called the MC7 code (Machine Code 7). Unlike S5, Siemens does not publish a separate, standalone "machine code table" for the S7 platform; the opcode and operand encodings are integrated into the AWL reference manual and the CPU-specific operating instructions.
This reference consolidates the encoding model, instruction categories, operand encoding rules, and the official Siemens documents that contain the per-instruction opcode tables. It is written for engineers who need to read or generate S7 machine code outside STEP 7 — for example, for cross-compilers, third-party runtimes, code-analysis tools, or forensic work on PLC memory dumps.
Instruction Format Architecture
Every S7 STL instruction in the compiled user program occupies an integer number of bytes and has the following general layout:
-
Opcode field (1 or 2 bytes): Identifies the operation. Basic instructions (bit logic, simple loads/transfers) use a single byte; extended instructions, parameterized functions, and CPU-specific extensions use a two-byte opcode where the first byte is a prefix (often
0x00-0x0Frange) and the second byte identifies the actual operation. -
Parameter field (0-N bytes): Encodes the operand. The width depends on the address type:
- No operand: 0 bytes (e.g.,
SET,CLR,NOP0/1). - Implicit operand: 0 additional bytes (e.g.,
NOT,SAVEoperate on the accumulator or status word). - Bit operand: 2 bytes for byte/bit address, 0 or 1 byte for area prefix depending on context.
- Byte/word/double-word operand: 1 byte for area, 2 bytes for byte address (16 bits).
- Constant: 1 type byte + 1/2/4 bytes of value.
- No operand: 0 bytes (e.g.,
The first byte of any operand block is the area identifier that selects the memory area. Common area codes used by the S7-300/400 are summarized below. The exact values used internally are documented in the AWL reference manual, but engineers analyzing a memory image can recognize areas by the high nibble and the consistent ordering of the address bytes.
| Area | Typical Use | Address Width |
|---|---|---|
| E / I (Process Input, PII) | Input image (PII) | Bit / Byte / Word / DWord |
| A / Q (Process Output, PIQ) | Output image (PIQ) | Bit / Byte / Word / DWord |
| M (Flag / Merker) | Bit memory / scratch | Bit / Byte / Word / DWord |
| L (Local Data / Temp) | Temporary stack data | Bit / Byte / Word / DWord |
| DB (Data Block) | DBX / DBB / DBW / DBD | Open via OPN or with DBn prefix |
| DI (Instance DB) | Multi-instance | Same encoding as DB |
| STW / ACCU | Status word, accumulators 1/2 | Implicit (no address bytes) |
| Constant | Literal values | 1 type byte + value bytes |
Opcode Byte Encoding Model
The S7 MC7 opcode map is a dense one-byte table for the common instructions, extended with a two-byte form (0x00-0x0F prefix) for the remainder. The mapping is intentionally aligned with the high-level grouping of the AWL language so that code-analysis tools can recover mnemonic information directly from the opcode byte without consulting a full lookup table.
Encoding Conventions
- The opcode byte is the first byte of any compiled AWL instruction.
- For two-byte opcodes, the second byte carries the operation; the first byte is the opcode-class prefix.
- The parameter field is in little-endian byte order, consistent with the byte order used by the S7 CPU when loading word and double-word values from the operand area.
- Bit addresses are encoded as
byte_number × 8 + bit_numberfor the bit-portion, and the high-order bits encode the byte number. This lets a 16-bit word hold a full bit address without separate bytes. - Constant operands carry a type byte that specifies the value width (1/2/4 bytes) and the interpretation (signed integer, unsigned, BCD, real, S5TIME, TIME, DATE, TOD, S7 string, etc.).
Bit Logic Instructions
Bit logic operates on the RLO (Result of Logic Operation) bit of the status word. The first scan of a network sets RLO to "1"; U (AND), UN (AND-NOT), O (OR), ON (OR-NOT), and X / XN (exclusive OR) combine RLO with the addressed operand and write the result back to RLO. The compiled instruction in MC7 is two bytes for a direct bit access: one byte for the opcode-with-area, one byte for the bit address. U( and O( open a parenthesized expression and store the current RLO on the nesting stack; ) closes it. The parenthesized versions are encoded as single-byte opcodes with no operand.
| AWL Mnemonic | Opcode Byte | Notes |
|---|---|---|
| U <bit> | 0x10 (illustrative range) | Single-bit operand follows |
| UN <bit> | 0x11 | Negated AND |
| O <bit> | 0x12 | OR |
| ON <bit> | 0x13 | OR-NOT |
| X <bit> | 0x14 | Exclusive OR |
| XN <bit> | 0x15 | Exclusive OR-NOT |
| U( | 0x18 | Push RLO |
| O( | 0x1A | Push RLO, OR-begin |
| ) | 0x19 | Pop, combine |
| SET | 0x1C | Force RLO = 1 |
| CLR | 0x1D | Force RLO = 0 |
| NOT | 0x1E | Negate RLO |
| SAVE | 0x1F | Save RLO into BR |
Set / Reset, Edge Detection, and Bit Assignment
The output instructions S (set), R (reset), = (assign), and the edge detectors FP (rising edge) and FN (falling edge) share the bit-logic opcode group. FP and FN allocate an edge bit in the local data (L stack) implicitly; the compiled form references the address and signals to the firmware that the edge-bit field is the following two bytes. SPB, SPL, SPM, SPN, SPO, SPZ, SPP, SPM, etc., are jump operations that branch on status bits. They are encoded as single-byte opcodes with a two-byte relative jump offset (16-bit signed) and a three-byte label identifier if the jump is symbolic.
| Mnemonic | Function | Encoding Note |
|---|---|---|
| S <bit> | Set bit if RLO = 1 | Opcode + 2-byte bit address |
| R <bit> | Reset bit if RLO = 1 | Opcode + 2-byte bit address |
| = <bit> | Assign RLO to bit | Opcode + 2-byte bit address |
| FP <bit> | Rising edge on <bit> | Opcode + 2 bytes address + 2 bytes edge-bit L-stack offset |
| FN <bit> | Falling edge on <bit> | Opcode + 2 bytes address + 2 bytes edge-bit L-stack offset |
| JU <label> | Unconditional jump | Opcode + 2-byte rel. offset (+ optional 3-byte label id) |
| JC / JCN / JCB / JNB | Conditional jump on RLO / BR | Opcode + 2-byte rel. offset |
| SPB / SPBN | Jump if RLO = 1 / 0 | Opcode + 2-byte rel. offset |
| SPZ / SPP / SPM / SPO | Status-bit jumps | Opcode + 2-byte rel. offset |
| SPL | Program branch (jump-distributor) | Opcode + 1-byte count + n × (2-byte offset) |
| LOOP | Loop on ACCU1-L | Opcode + 2-byte rel. offset |
Timers and Counters
Timers and counters are encoded with a one-byte opcode (different for each) and a two-byte parameter word. The parameter word carries the timer/counter number (bits 0-7) and the time-base (high bits) for timers, or just the counter number for counters. SI (pulse), SV (extended pulse), SE (on-delay), SS (latched on-delay), SA (off-delay) all share the timer group opcode; the specific variant is signaled by a sub-field in the parameter word. FR (enable), L (load current value into ACCU1), LC (load BCD-coded), and R (reset) round out the timer instruction set.
| Mnemonic | Encoding |
|---|---|
| SI / SV / SE / SS / SA | Opcode byte + 2-byte T-number / time-base |
| FR T<n> | Free (enable) timer |
| L T<n> | Load timer (binary) into ACCU1 |
| LC T<n> | Load timer (BCD) into ACCU1 |
| R T<n> | Reset timer |
| CU / CD / S / R / FR / L / LC C<n> | Counter group, same encoding pattern |
Load and Transfer Instructions
The L (Load) and T (Transfer) instructions move data between operands and the accumulators. L reads the operand into ACCU1, shifting the previous ACCU1 to ACCU2. T writes ACCU1 (low word for byte ops) to the operand and clears ACCU1. The encoding for a direct byte/word/dword operand is one opcode byte plus a parameter block: one area byte + two address bytes for symbolics like MB, MW, MD, DBB, DBW, DBD, etc.
Immediate constants (L 123, L L#+123, L B#16#1A, L 2#00010101, L 1.234e-5, L S5T#1s, L T#1d_2h, L D#2004-04-01, L TOD#12:34:56, L C#123) use a constant-type prefix byte plus the typed value. The constant type byte encodes both the width (1/2/4 bytes) and the interpretation (signed/unsigned/BCD/real/date-time), letting the firmware perform the correct conversion on load. LAR1 / LAR2 load the AR1 / AR2 address registers; TAR1 / TAR2 transfer them back. +AR1 / +AR2 and -AR1 / -AR2 add/subtract a 16-bit signed offset to the address register.
Comparison Instructions
Comparison instructions operate on ACCU2 vs. ACCU1, set the status bits CC 0/CC 1/CC 2/CC 3, and clear RLO. Six relations are provided: == (equal), <> (not equal), > (greater), >= (greater or equal), < (less), <= (less or equal). The !== and !> forms are STEP 7 V5.x extensions for unsigned comparisons; they are CPU-firmware dependent. Each comparison variant is encoded with its own opcode byte and an operand field identical to the load instruction of the same width.
Conversion Instructions
The conversion set is the largest single group in the AWL manual. Encoded as two-byte opcodes (prefix + sub-opcode), the conversions include integer-to-BCD, BCD-to-integer, integer-to-real, real-to-integer (rounding-down, -up, -truncate), complement-one, complement-two, negate, swap bytes within a word, swap words within a double-word, mirror, and the IEC 1131 ROUND / TRUNC / CEIL / FLOOR real-to-integer forms. BTD, BTI, DTB, DTR, ITB, ITD, RND, RND+, RND-, TRUNC, CEIL, FLOOR, NEGI, NEGD, NEGR, INVI, INVD, TAW, TAD, CAD are all documented with their opcode values in the AWL reference manual.
Word Logic and Shift / Rotate
Word logic operates ACCU1 and ACCU2 with the same relations as bit logic. UW (AND word), OW (OR word), XOW (XOR word), UD / OD / XOD are the double-word forms. Shifts: SLW / SLD (shift left), SRW / SRD (shift right) — the shift count is in ACCU2-L. SSI / SSD (shift with sign) and RLD / RRD / RLDA / RRDA (rotate through CC 1, rotate direct) round out the group. All are single-byte opcodes with a one-byte constant operand (the shift count) when the count is literal, or no operand when the count comes from ACCU2-L.
Program Control and Block Calls
Block calls (CALL FB/FC/SFB/SFC, UC unconditional, CC conditional) are encoded with the block type and number, plus a parameter list of pointers to the actual operands. CALL with formal parameters encodes a parameter descriptor for each Pi/Po/PiPo (input/output/in-out). OPN opens a data block and shifts the current DB into the DI register. DB / DI prefix accessors use a one-byte area identifier plus the DB number. BEA, BEB (block-end absolute, conditional) and CBL (block-call list) are documented in the AWL reference.
Locating the Official Opcode Documentation
Siemens does not release a standalone "machine code table" equivalent to the S5 AG 100 manual. The opcode information is contained in two complementary documents:
- Anweisungsliste (AWL) für S7-300/400 — Reference Manual (PDF). This is the canonical AWL manual covering S7-300 and S7-400. It documents every instruction with the operands, allowed areas, status-word effects, and example snippets. The opcode values appear inline in the instruction tables.
-
S7-300 / S7-400 CPU operating instructions. The CPU-specific manual for each order number (e.g.,
6ES7 315-2EH14-0AB0) lists the CPU's exact instruction set, including any extension instructions that are not part of the base AWL manual. Look in the "Instruction list" appendix of the CPU manual. - STEP 7 online help. The integrated help in STEP 7 V5.x and in the TIA Portal reproduces the same tables in HTML form. It is searchable and is the most practical source when working at a PC with STEP 7 installed.
- Siemens Industry Online Support portal. The portal at support.industry.siemens.com is the entry point for all of the above documents. The Siemens Knowledge Base articles are searchable by order number, firmware version, and instruction name.
Practical Decoding Example
The following AWL snippet illustrates the typical encoding shape. The exact byte values are CPU- and firmware-dependent; the structure, however, is invariant.
AWL Source Compiled Encoding (illustrative)
------- ------------------------------
U E 0.0 [opcode] [bit_addr: 0x0000]
U E 0.1 [opcode] [bit_addr: 0x0001]
= A 4.0 [opcode] [bit_addr: 0x0020]
L MW 10 [opcode] [area: M] [addr: 0x000A]
L 1234 [opcode] [type: W#] [value: 0x04D2]
+I [opcode] (no operand)
T MW 20 [opcode] [area: M] [addr: 0x0014]
When reading a memory dump, the opcode is the disambiguator: grouping contiguous opcodes by family (bit logic, load/transfer, math, conversion, control) and walking the parameter fields in order reconstructs the original AWL. Cross-reference each opcode against the AWL reference manual to confirm the variant (e.g., the L opcode changes meaning when the operand is a constant vs. a memory area).
Differences vs. Simatic S5
The S5 AG 100 ("Automatisierungsgerät 100") manual documented the S5 instruction set down to the binary level, with explicit opcode tables. S5 used a one-byte opcode per instruction and a separate address byte for the memory-area selection. S7 reorganized the encoding into the MC7 format described above, and Siemens changed the documentation strategy from a dedicated machine-code reference to instruction-by-instruction tables embedded in the AWL manual. If you are porting S5 disassembler logic, expect to redo the opcode lookup and to handle the two-byte extended opcodes that S7 introduces.
Tools and Workflows
Engineers who routinely work with S7 machine code outside STEP 7 typically combine the following:
- STEP 7 with the integrated AWL/STL editor for online/offline block view and cross-reference.
- STEP 7 "Monitor/Modify" with symbolic display for runtime verification of decoded operands.
- Custom disassemblers built around the opcode tables in the AWL reference manual and the CPU-specific instruction-list appendix.
-
Memory-card extraction tools (e.g., Simatic Memory Card readers plus
ddor equivalent) for raw binary analysis. - S7-PCT, S7-SCL, and the S7-Graph option packages for verifying that reconstructed source compiles to the same machine image.
Verification Workflow
- Identify the CPU order number and firmware version from the module's label or from STEP 7 online diagnostics.
- Open the CPU's manual in Siemens Industry Online Support and locate the "Instruction list" appendix. Note any CPU-specific extensions.
- Cross-check the table against the base AWL reference manual at support.industry.siemens.com — Anweisungsliste (AWL) für S7-300/400 (PDF) for the base opcodes.
- Compare the disassembled opcodes with both tables. Disagreements indicate a STEP 7 version mismatch or a non-standard cross-compiler; resolve by upgrading STEP 7 or by pinning the cross-compiler to the matching CPU firmware.
- Reload the source block into STEP 7 and use "Block comparison" (Online → Block Comparison) to confirm the recompiled image is bit-identical to the original. This is the gold standard for verifying manual decoding.
FAQ
Where is the S7 machine code (MC7) opcode table documented?
Siemens does not publish a separate "machine code table." The opcode values are listed in the AWL (STL) reference manual, available at support.industry.siemens.com — Anweisungsliste (AWL) für S7-300/400 (PDF), with CPU-specific extensions in the operating instructions of each CPU order number.
Does the S7-300 and S7-400 use the same opcodes?
The base instruction set is shared, but CPU firmware versions add extensions (e.g., ROUND, CEIL, FLOOR, TRUNC, !==, !>, the long-word forms). Always match the instruction set to the CPU order number and firmware version listed in the Siemens Knowledge Base.
How are constants like S5TIME, TIME, DATE, or TOD encoded in a Load instruction?
The Load instruction with a typed constant uses a constant-type prefix byte plus the value. The type byte selects among 8/16/32-bit signed/unsigned, BCD, real, S5TIME, TIME, DATE, TOD, S7 string, counter, and pointer types; the value bytes follow in little-endian order. See the AWL reference for the full type-code table.
Can I patch the binary program block directly on a live CPU?
No. S7 programs are protected by checksums and online reference data; all modifications must go through STEP 7 to maintain block consistency. Use STEP 7's online block editor and the standard download procedure.
Why is the S7 machine code referred to as MC7?
MC7 is the informal name for the S7 CPU instruction set (Machine Code 7) to distinguish it from the S5 instruction set. The name is used in Siemens technical documentation and in third-party tooling but is not the title of any single published manual.