If MikaTech was a bad company, you could find tons of bad reputations about its service on the internet over the 28 years history
So, the answer is YES! We are good people.Why choose Mikatech, please click here to find out
About MikaTech
Time went fast, from the day we did our first 8051 MCU reverse engineering project in 1998, to the day we set up our million dollar reverse engineering lab in 2012, 14 years went by. Now we start our new business of embedded visual system development, hope we can serve another 10 years.
Peter Lee
Co-Founder & CEO
Writing microcontroller programs mainly consists of issuing instructions (commands) in a specific execution sequence to complete designated tasks. Electronic hardware cannot interpret human-readable logic such as "If the pushbutton is pressed, turn on the light". Instead, developers must use a series of simple, strictly defined commands recognizable by the MCU’s internal decoder. The full collection of these valid commands is known as the instruction set. All 8051-compatible microcontrollers feature a total of 255 distinct instructions, meaning there are 255 unique machine words available for program development.
At first glance, memorizing this large set of symbolic opcodes seems intimidating. However, the actual learning burden is far lighter than it appears. Many instructions count as separate entries even though they execute identical underlying operations, leaving only 111 functionally unique commands. For example, ADD A,R0, ADD A,R1, ..., ADD A,R7 all perform the same addition operation between the accumulator and a working register. Since there are eight working registers, each variant is listed as a separate instruction entry. Considering that all instructions only implement 53 core operations (addition, subtraction, data copy, etc.) and most of these operations are rarely used in practical projects, developers only need to master roughly 20 to 30 mnemonics — a very manageable amount.
Beyond functional program execution, the instruction set forms the first line of defense against unauthorized firmware access. Most embedded systems rely on lockbit mechanisms to block external readback of internal flash or EEPROM memory. Nevertheless, thorough comprehension of each instruction’s runtime behavior is essential for both writing secure production firmware and conducting legitimate reverse engineering to recover lost source code. Attackers frequently exploit specific instruction behaviors to bypass lock protection, leveraging fault injection, timing analysis, and other side-channel techniques to trigger an unlock state. In many attack scenarios, physical chip decapsulation paired with microprobing directly reads fuse status bits, enabling complete binary dumps of the stored firmware. The ability to replicate a device’s full functionality often hinges on successful firmware extraction via these methods, making firmware recovery a critical skill within embedded security research.
All instructions are categorized into five core groups based on the operations they perform:
The first segment of every instruction is called a mnemonic, which represents the core operation to be executed (data copy, arithmetic addition, bitwise logic, etc.). Mnemonics are shortened abbreviations for the full name of each hardware operation. Example definitions are shown below:
INC R1 – Increment the value stored in register R1 by one;LJMP LAB5 – Perform a long unconditional jump to the memory address labeled LAB5;JNZ LOOP – Jump to the address labeled LOOP if the accumulator value is non-zero;The second segment of an instruction is the operand, separated from the mnemonic by at least one whitespace character, and it defines the data targets processed by the operation. Some instructions carry no operands, while others include one, two, or three operands. Multiple operands within a single instruction are separated by commas. Examples:
RET – Return execution flow from a subroutine;JZ TEMP – Jump to the address labeled TEMP if the accumulator value equals zero;ADD A,R3 – Add the value of register R3 to the accumulator;CJNE A,#20,LOOP – Compare the accumulator against the immediate constant 20; jump to LOOP if the two values are unequal;Each instruction category plays a distinct role in the device’s overall security posture. Bit-oriented instructions directly manipulate lockbits and other security configuration fuses. Data transfer opcodes such as MOVC read code memory, and these instructions return garbled invalid data when the lockbit protection is active. Reverse engineering workflows frequently focus on identifying instruction sequences that validate the lock state, then attempting to skip these validation branches via clock glitching or program counter tampering. In some cases, recovering a bricked locked MCU requires locating hidden bootloader backdoors that utilize specific branch instructions to enable full memory readback.
Arithmetic instructions execute fundamental mathematical operations including addition, subtraction, multiplication, and division. After computation completes, the resulting value is stored inside the first specified operand. Example:
ADD A,R1 – The sum of accumulator A and register R1 is saved back into the accumulator register.
| Arithmetic Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ADD A,Rn | Add working register content to accumulator | 1 | 1 |
| ADD A,direct | Add direct-address byte to accumulator | 2 | 2 |
| ADD A,@Ri | Add indirectly addressed internal RAM byte to accumulator | 1 | 2 |
| ADD A,#data | Add immediate constant value to accumulator | 2 | 2 |
| ADDC A,Rn | Add register to accumulator with carry flag input | 1 | 1 |
| ADDC A,direct | Add direct byte to accumulator with carry flag input | 2 | 2 |
| ADDC A,@Ri | Add indirect RAM byte to accumulator with carry flag input | 1 | 2 |
| ADDC A,#data | Add immediate constant to accumulator with carry flag input | 2 | 2 |
| SUBB A,Rn | Subtract register from accumulator with borrow flag input | 1 | 1 |
| SUBB A,direct | Subtract direct byte from accumulator with borrow flag input | 2 | 2 |
| SUBB A,@Ri | Subtract indirect RAM byte from accumulator with borrow flag input | 1 | 2 |
| SUBB A,#data | Subtract immediate constant from accumulator with borrow flag input | 2 | 2 |
| INC A | Increment accumulator value by one | 1 | 1 |
| INC Rn | Increment working register value by one | 1 | 2 |
| INC Rx | Increment direct-address byte by one | 2 | 3 |
| INC @Ri | Increment indirectly addressed RAM byte by one | 1 | 3 |
| DEC A | Decrement accumulator value by one | 1 | 1 |
| DEC Rn | Decrement working register value by one | 1 | 1 |
| DEC Rx | Decrement direct-address byte by one | 1 | 2 |
| DEC @Ri | Decrement indirectly addressed RAM byte by one | 2 | 3 |
| INC DPTR | Increment 16-bit data pointer register by one | 1 | 3 |
| MUL AB | Multiply accumulator A by register B | 1 | 5 |
| DIV AB | Divide accumulator A by register B | 1 | 5 |
| DA A | Decimal adjust accumulator for BCD arithmetic results | 1 | 1 |
Arithmetic instructions serve more than pure data processing tasks; they are integral to checksum verification and encryption routines that validate firmware integrity. Attackers who can corrupt addition or subtraction results via voltage glitching may bypass security checks that compare calculated checksums against stored reference values. This manipulation can trigger an unlock sequence even when the lockbit fuse remains set. For firmware extraction workflows, deep knowledge of ALU arithmetic behavior enables crafting targeted fault injection attacks designed to skip lock validation logic. Additionally, the carry (C) and overflow (OV) status flags are frequent attack targets: glitching the arithmetic logic unit can force incorrect flag states and evade critical lock-state comparison checks.
Branch instructions fall into two distinct categories:
Unconditional jump instructions: Upon execution, the CPU immediately jumps to a new memory address and resumes program flow from that location with no preconditions.
Conditional jump instructions: A jump to an alternate program address only executes if a specified logical condition evaluates true. If the condition fails, the CPU proceeds sequentially to the next instruction in memory.
| Branch Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ACALL addr11 | Absolute 2KB-page subroutine call | 2 | 6 |
| LCALL addr16 | Full 64KB address long subroutine call | 3 | 6 |
| RET | Return execution from standard subroutine | 1 | 4 |
| RETI | Return execution from interrupt service routine | 1 | 4 |
| AJMP addr11 | Absolute jump within current 2KB memory page | 2 | 3 |
| LJMP addr16 | Long jump to any 64KB program memory address | 3 | 4 |
| SJMP rel | Short relative jump (-128 to +127 offset from next instruction) | 2 | 3 |
| JC rel | Short jump if carry flag C is set | 2 | 3 |
| JNC rel | Short jump if carry flag C is cleared | 2 | 3 |
| JB bit,rel | Short jump if specified direct bit is logic 1 | 3 | 4 |
| JBC bit,rel | Jump if direct bit set, then clear the target bit (short jump) | 3 | 4 |
| JMP @A+DPTR | Indirect indexed jump using accumulator + data pointer offset | 1 | 2 |
| JZ rel | Short jump if accumulator equals zero | 2 | 3 |
| JNZ rel | Short jump if accumulator holds non-zero value | 2 | 3 |
| CJNE A,direct,rel | Compare accumulator and direct byte; short jump if values unequal | 3 | 4 |
| CJNE A,#data,rel | Compare accumulator and immediate constant; short jump if unequal | 3 | 4 |
| CJNE Rn,#data,rel | Compare working register and immediate constant; short jump if unequal | 3 | 4 |
| CJNE @Ri,#data,rel | Compare indirect RAM byte and constant; short jump if unequal | 3 | 4 |
| DJNZ Rn,rel | Decrement register, short jump if result non-zero | 2 | 3 |
| DJNZ Rx,rel | Decrement direct byte, short jump if result non-zero | 3 | 4 |
| NOP | No operation (clock cycle delay placeholder) | 1 | 1 |
Branch instructions form the core of conditional program logic, including all critical security validation routines. The JB opcode, for instance, is widely deployed to test lockbit fuse status. If the lockbit is set, the program jumps to a security subroutine that disables debug interfaces and blocks memory readback. Attackers can target JB instruction execution with clock glitching to force the hardware to treat a set lockbit as cleared, fully unlocking the microcontroller. Similarly, CJNE instructions power password verification loops; injecting a timing or voltage fault mid-comparison can redirect the program counter to an unintended address, exposing protected firmware code. Within reverse engineering workflows, mapping the full branch control flow graph is mandatory to locate legitimate unlock paths and patch binary firmware for data recovery.
Data transfer opcodes copy values from one register or memory location to another, leaving the source data unmodified. Instructions carrying the "X" suffix (MOVX) facilitate data exchange with external RAM memory spaces.
| Data Transfer Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| MOV A,Rn | Copy working register value into accumulator | 1 | 1 |
| MOV A,direct | Copy direct-address byte into accumulator | 2 | 2 |
| MOV A,@Ri | Copy indirectly addressed internal RAM byte into accumulator | 1 | 2 |
| MOV A,#data | Load immediate constant value into accumulator | 2 | 2 |
| MOV Rn,A | Copy accumulator value into working register | 1 | 2 |
| MOV Rn,direct | Copy direct-address byte into working register | 2 | 4 |
| MOV Rn,#data | Load immediate constant into working register | 2 | 2 |
| MOV direct,A | Copy accumulator value into direct-address byte | 2 | 3 |
| MOV direct,Rn | Copy working register value into direct-address byte | 2 | 3 |
| MOV direct,direct | Copy one direct-address byte to another direct location | 3 | 4 |
| MOV direct,@Ri | Copy indirect RAM byte to direct-address byte | 2 | 4 |
| MOV direct,#data | Load immediate constant into direct-address byte | 3 | 3 |
| MOV @Ri,A | Copy accumulator value into indirectly addressed RAM byte | 1 | 3 |
| MOV @Ri,direct | Copy direct-address byte into indirect RAM location | 2 | 5 |
| MOV @Ri,#data | Load immediate constant into indirect RAM byte | 2 | 3 |
| MOV DPTR,#data | Load 16-bit immediate constant into data pointer register | 3 | 3 |
| MOVC A,@A+DPTR | Read code memory byte at offset A+DPTR into accumulator | 1 | 3 |
| MOVC A,@A+PC | Read code memory byte at offset A+PC into accumulator | 1 | 3 |
| MOVX A,@Ri | Read 8-bit addressed external RAM byte into accumulator | 1 | 3-10 |
| MOVX A,@DPTR | Read 16-bit addressed external RAM byte into accumulator | 1 | 3-10 |
| MOVX @Ri,A | Write accumulator value to 8-bit external RAM address | 1 | 4-11 |
| MOVX @DPTR,A | Write accumulator value to 16-bit external RAM address | 1 | 4-11 |
| PUSH direct | Push direct-address byte onto system stack | 2 | 4 |
| POP direct | Pop top stack value into direct-address byte | 2 | 3 |
| XCH A,Rn | Swap full byte values between accumulator and working register | 1 | 2 |
| XCH A,direct | Swap full byte values between accumulator and direct byte | 2 | 3 |
| XCH A,@Ri | Swap full byte values between accumulator and indirect RAM byte | 1 | 3 |
| XCHD A,@Ri | Swap only lower 4-bit nibble of accumulator and indirect RAM byte | 1 | 3 |
Data transfer instructions appear most frequently in all embedded firmware and simultaneously represent critical attack surfaces for security exploits. MOVC opcodes are exclusively designed to read program code memory; when lockbit protection is active, these instructions return corrupted meaningless data. However, applying precise voltage glitching during MOVC execution can force the MCU to output unmodified original code bytes, enabling bytewise flash dump attacks widely used in side-channel reverse engineering. MOVX instructions access unencrypted external memory buses, which adversaries can passively monitor with logic analyzers to fully duplicate firmware without tampering with internal security fuses. For internal EEPROM storage, MOV direct variants enable read/write access to special function registers controlling lock fuse state; unclosed debug interfaces allow attackers to leverage simple MOV sequences to unlock the chip and perform full memory extraction. PUSH and POP manage stack memory, a common target for stack overflow exploits that overwrite return addresses and redirect execution to malicious unlock subroutines. During forensic recovery of locked embedded hardware, analysts trace all MOV instruction sequences to locate undocumented manufacturer backdoors intentionally left for factory device reflashing.
Logic instructions execute bitwise logical operations across matching bit positions of two byte operands, storing the final computed result inside the first operand register.
| Logic Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ANL A,Rn | Bitwise AND working register with accumulator | 1 | 1 |
| ANL A,direct | Bitwise AND direct-address byte with accumulator | 2 | 2 |
| ANL A,@Ri | Bitwise AND indirect RAM byte with accumulator | 1 | 2 |
| ANL A,#data | Bitwise AND immediate constant with accumulator | 2 | 2 |
| ANL direct,A | Bitwise AND accumulator with direct-address byte, store result in direct byte | 2 | 3 |
| ANL direct,#data | Bitwise AND immediate constant with direct-address byte | 3 | 4 |
| ORL A,Rn | Bitwise OR working register with accumulator | 1 | 1 |
| ORL A,direct | Bitwise OR direct-address byte with accumulator | 2 | 2 |
| ORL A,@Ri | Bitwise OR indirect RAM byte with accumulator | 1 | 2 |
| ORL direct,A | Bitwise OR accumulator with direct-address byte, store result in direct byte | 2 | 3 |
| ORL direct,#data | Bitwise OR immediate constant with direct-address byte | 3 | 4 |
| XRL A,Rn | Bitwise XOR working register with accumulator | 1 | 1 |
| XRL A,direct | Bitwise XOR direct-address byte with accumulator | 2 | 2 |
| XRL A,@Ri | Bitwise XOR indirect RAM byte with accumulator | 1 | 2 |
| XRL A,#data | Bitwise XOR immediate constant with accumulator | 2 | 2 |
| XRL direct,A | Bitwise XOR accumulator with direct-address byte, store result in direct byte | 2 | 3 |
| XRL direct,#data | Bitwise XOR immediate constant with direct-address byte | 3 | 4 |
| CLR A | Zero out all bits of accumulator register | 1 | 1 |
| CPL A | Bitwise invert all bits inside accumulator | 1 | 1 |
| SWAP A | Swap upper 4-bit nibble and lower 4-bit nibble within accumulator | 1 | 1 |
| RL A | Rotate accumulator bits left one position (no carry involvement) | 1 | 1 |
| RLC A | Rotate accumulator left through carry flag bit | 1 | 1 |
| RR A | Rotate accumulator bits right one position (no carry involvement) | 1 | 1 |
| RRC A | Rotate accumulator right through carry flag bit | 1 | 1 |
Bitwise logic instructions are heavily utilized to mask and manipulate lockbit fuses and other critical security configuration registers. For example, ANL masks can selectively clear individual bits within security control SFRs, while ORL masks set specific fuse enable bits. Attackers capable of injecting timing or voltage faults mid-execution of these logic opcodes may accidentally toggle the lockbit state and fully unlock the microcontroller. Additionally, XRL exclusive OR instructions form the foundation of common firmware obfuscation and lightweight encryption routines; reversing the XOR masking operation allows adversaries to recover plaintext security keys stored inside EEPROM memory. For firmware extraction workflows, deep comprehension of bitwise logic operations is mandatory to decrypt obfuscated protected code segments before initiating full binary memory dumps.
Bit-oriented instructions perform logical operations analogous to the byte-wide logic group, but they operate exclusively on single individual bit locations rather than full 8-bit bytes.
| Bit-oriented Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| CLR C | Clear carry flag status bit to logic 0 | 1 | 1 |
| CLR bit | Clear specified direct bit-addressable location to logic 0 | 2 | 3 |
| SETB C | Set carry flag status bit to logic 1 | 1 | 1 |
| SETB bit | Set specified direct bit-addressable location to logic 1 | 2 | 3 |
| CPL C | Invert logic state of carry flag bit | 1 | 1 |
| CPL bit | Invert logic state of specified direct bit location | 2 | 3 |
| ANL C,bit | Bitwise AND target direct bit with carry flag, store result in C | 2 | 2 |
| ANL C,/bit | Bitwise AND inverted target bit with carry flag, store result in C | 2 | 2 |
| ORL C,bit | Bitwise OR target direct bit with carry flag, store result in C | 2 | 2 |
| ORL C,/bit | Bitwise OR inverted target bit with carry flag, store result in C | 2 | 2 |
| MOV C,bit | Copy logic state of direct bit into carry flag register | 2 | 2 |
| MOV bit,C | Copy logic state of carry flag into specified direct bit location | 2 | 3 |
Bit-oriented opcodes represent the primary software interface for manipulating lockbit fuses and other security-critical single-bit configuration flags. SETB and CLR can directly alter lock fuse state values, though most modern 8051 derivative MCUs harden hardware protections to render lockbit registers read-only during normal runtime execution. Critical software bugs allowing write access to these bit-addressable security registers create remote unlock attack vectors for malicious actors. The MOV C,bit instruction reads lock fuse status and transfers the value into the carry flag, which subsequent JC/JNC conditional branches evaluate to enforce memory access restrictions. This standard lock-check instruction sequence is a primary target for glitch injection attacks: artificially flipping the carry flag bypasses the entire security validation branch. In physical decapsulation-based chip attacks, microprobing directly accesses these bit fuse locations to read raw lock state bits, enabling full unobstructed program memory dumps without modifying any firmware code.
Below is a reference glossary defining every standard operand notation used across the 8051 instruction set:
These operand notations define the full spectrum of 8051 addressing modes and are essential for locating lockbit fuse addresses within the chip’s memory map. A standard reverse engineering workflow scans binary firmware for direct operand references pointing to security SFR memory addresses, then traces all read/write instruction paths targeting those registers. This static analysis frequently uncovers undocumented factory test modes or hidden backdoor code paths that enable full memory readback even when lockbit protection remains active. For legitimate firmware data recovery projects, precise understanding of each operand type allows accurate reconstruction of full memory dump layouts and proper interpretation of extracted binary code binaries.
ACALL addr11 – Absolute 2KB-page subroutine call
addr11: Target subroutine memory address (11-bit page offset)
Description: This opcode unconditionally pushes the return program counter address onto the system stack and jumps execution to the specified subroutine address. A critical constraint applies: the current instruction’s following byte and the target subroutine entry point must reside within the identical 2KB program memory page boundary.
Syntax: ACALL [subroutine_label];
Instruction Bytes: 2 (opcode byte, 11-bit address payload);
PSW Status Flags Affected: No status flags modified by this instruction.
EXAMPLE:
Pre-execution PC value = 0123h
Post-execution PC value = 0345h
This subroutine call opcode appears frequently inside MCU bootloader firmware. Attackers capable of overwriting the 11-bit addr11 operand via buffer overflow memory corruption can redirect program execution to custom unlock subroutines that disable lockbit protections. In most reverse engineering recovery scenarios, binary patching of the ACALL target address represents a straightforward method to enable full flash firmware extraction.
ADD A,Rn – Add working register value to accumulator register
A: Accumulator register
Rn: Any working register from R0 to R7
Description: The opcode performs unsigned byte addition between the accumulator and the selected working register Rn, storing the resulting sum back into the accumulator register.
Syntax: ADD A,Rn;
Writing firmware for microcontrollers essentially means sending ordered, predefined instructions to accomplish designated tasks. Electronic hardware cannot interpret high-level descriptive logic such as "if a pushbutton is pressed, activate the LED"; instead, it only recognizes a limited set of low-level standardized commands decoded by its internal circuitry. This complete set of valid commands is referred to as the INSTRUCTION SET. All 8051-compatible microcontrollers feature a total of 255 distinct instruction opcodes available for program development.
At first glance, the extensive list of mnemonic syntaxes may appear overwhelming to memorize. However, the complexity is deceptive. Many opcodes execute identical underlying operations with different addressing modes, meaning there are only 111 unique functional operations in practice. For instance, ADD A,R0, ADD A,R1 through ADD A,R7 all perform accumulator addition with a working register, and each variant counts as a separate opcode due to different register encoding. When accounting for the 53 core mathematical, logical and data transfer operations (most rarely used in practical projects), developers only need to master roughly 20 to 30 unique mnemonic abbreviations for regular programming.
Beyond core functional programming, the instruction set is tightly coupled with the microcontroller’s embedded security architecture. Most modern 8051 derivative chips implement lockbit fuses designed to block unauthorized external dumping of on-chip Flash and EEPROM storage. Mastery of the full instruction set is mandatory for both implementing robust anti-tamper protection schemes and conducting legitimate firmware reverse engineering and data recovery. Malicious attackers frequently exploit specific instruction behaviors to bypass lock mechanisms via fault injection, timing side-channel analysis, or physical probing attacks. In numerous real-world hardware cracking scenarios, full chip decapsulation paired with die microprobing is used to directly read fuse status bits, enabling complete binary extraction. The ability to replicate a protected device’s proprietary logic almost always hinges on successful firmware dumping through these attack vectors, making instruction-level analysis a foundational skill in embedded hardware security research.
All 8051 instructions are categorized into five distinct groups based on their core functional behavior:
The first segment of every instruction is called the MNEMONIC, a short alphabetical abbreviation representing the core operation to execute (data copy, arithmetic addition, bitwise logic, jump, etc.). Mnemonics act as simplified shorthand for the full operation name. Representative examples are listed below:
INC R1 – Increment general-purpose register R1 by one;LJMP LAB5 – Perform a 16-bit long unconditional jump to the program label LAB5;JNZ LOOP – Jump to label LOOP if the accumulator value is non-zero;The secondary segment of an instruction is the OPERAND, separated from the mnemonic by at least one whitespace character, which defines the data, memory address or register target processed by the operation. Some instructions carry zero operands, while others include one, two, or three operands; multiple operands are separated by commas. Reference examples:
RET – Return execution flow from a subroutine to the caller;JZ TEMP – Jump to label TEMP when accumulator holds zero value;ADD A,R3 – Sum contents of register R3 with accumulator A;CJNE A,#20,LOOP – Compare immediate constant 20 against accumulator; jump to LOOP if values mismatch;Each instruction classification carries unique implications for device security. Bit-manipulation opcodes, for example, offer direct access to lockbit fuses and security configuration registers. Memory read instructions such as MOVC retrieve raw program code from Flash memory, returning garbled invalid bytes when lockbits are enabled. Reverse engineering workflows prioritize identifying instruction sequences that validate lock fuse states, then attempt to skip these verification branches via clock/voltage glitching or program counter tampering. In cases of bricked locked microcontrollers, forensic recovery often relies on locating hidden bootloader backdoors triggered by specific conditional branch opcodes to unlock full memory read access.
Arithmetic instructions execute fundamental mathematical operations including addition, subtraction, multiplication and division. Upon completion of calculation, the computed result overwrites the storage of the first listed operand. Sample demonstration: ADD A,R1 stores the sum of Accumulator A and Register R1 back into A.
| Arithmetic Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ADD A,Rn | Add register Rn value to accumulator A | 1 | 1 |
| ADD A,direct | Add directly addressed RAM/SFR byte to accumulator A | 2 | 2 |
| ADD A,@Ri | Add indirectly addressed RAM byte to accumulator A | 1 | 2 |
| ADD A,#data | Add 8-bit immediate constant to accumulator A | 2 | 2 |
| ADDC A,Rn | Add register Rn plus carry flag to accumulator A | 1 | 1 |
| ADDC A,direct | Add direct byte plus carry flag to accumulator A | 2 | 2 |
| ADDC A,@Ri | Add indirect RAM byte plus carry flag to accumulator A | 1 | 2 |
| ADDC A,#data | Add immediate constant plus carry flag to accumulator A | 2 | 2 |
| SUBB A,Rn | Subtract register Rn with borrow flag from accumulator A | 1 | 1 |
| SUBB A,direct | Subtract direct byte with borrow flag from accumulator A | 2 | 2 |
| SUBB A,@Ri | Subtract indirect RAM byte with borrow flag from accumulator A | 1 | 2 |
| SUBB A,#data | Subtract immediate constant with borrow flag from accumulator A | 2 | 2 |
| INC A | Increment accumulator A by one | 1 | 1 |
| INC Rn | Increment working register Rn by one | 1 | 2 |
| INC Rx | Increment directly addressed byte by one | 2 | 3 |
| INC @Ri | Increment indirectly addressed RAM byte by one | 1 | 3 |
| DEC A | Decrement accumulator A by one | 1 | 1 |
| DEC Rn | Decrement working register Rn by one | 1 | 1 |
| DEC Rx | Decrement directly addressed byte by one | 1 | 2 |
| DEC @Ri | Decrement indirectly addressed RAM byte by one | 2 | 3 |
| INC DPTR | Increment 16-bit data pointer register DPTR by one | 1 | 3 |
| MUL AB | 8-bit unsigned multiply of Accumulator A and Register B | 1 | 5 |
| DIV AB | 8-bit unsigned divide of Accumulator A by Register B | 1 | 5 |
| DA A | BCD decimal adjust correction for accumulator A post-addition | 1 | 1 |
Arithmetic opcodes serve dual purposes for data manipulation and security validation, commonly deployed to compute firmware integrity checksums and lightweight encryption routines. Attackers can alter ALU calculation outputs via voltage or clock glitching to invalidate checksum comparison logic, bypassing lock authentication sequences even when fuse bits remain active. For firmware extraction workflows, analyzing arithmetic unit flag generation (carry C, overflow OV, auxiliary carry AC) enables designing targeted fault injection attacks to skip lock validation subroutines. The carry and overflow status flags represent primary attack vectors; precise hardware glitches can force incorrect flag values to trick conditional jump logic responsible for enforcing memory access restrictions.
Two distinct categories of branch opcodes exist within the 8051 architecture:
Unconditional jump instructions: Upon execution, program flow unconditionally redirects to a target memory address for subsequent instruction processing.
Conditional jump instructions: Execution only branches to the target address if a predefined logical condition evaluates true; otherwise, the CPU continues sequentially with the next instruction in memory.
| Branch Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ACALL addr11 | Absolute 2KB page subroutine call (11-bit target address) | 2 | 6 |
| LCALL addr16 | Long full 64KB address space subroutine call (16-bit target) | 3 | 6 |
| RET | Return execution flow from standard subroutine | 1 | 4 |
| RETI | Return execution flow from interrupt service routine | 1 | 4 |
| AJMP addr11 | Absolute 2KB page unconditional jump (11-bit target address) | 2 | 3 |
| LJMP addr16 | Long full 64KB unconditional jump (16-bit target address) | 3 | 4 |
| SJMP rel | Short relative jump, offset range -128 ~ +127 bytes post-instruction | 2 | 3 |
| JC rel | Short jump if carry flag C is logic high (1) | 2 | 3 |
| JNC rel | Short jump if carry flag C is logic low (0) | 2 | 3 |
| JB bit,rel | Short jump if specified bit-addressable RAM/SFR bit equals 1 | 3 | 4 |
| JBC bit,rel | Jump if target bit set, then automatically clear the target bit | 3 | 4 |
| JMP @A+DPTR | Indirect indexed jump using A + DPTR computed target address | 1 | 2 |
| JZ rel | Short jump if accumulator A holds zero value | 2 | 3 |
| JNZ rel | Short jump if accumulator A holds non-zero value | 2 | 3 |
| CJNE A,direct,rel | Compare A vs direct byte; short jump if values mismatch | 3 | 4 |
| CJNE A,#data,rel | Compare A vs immediate constant; short jump if values mismatch | 3 | 4 |
| CJNE Rn,#data,rel | Compare working register Rn vs immediate constant; jump on mismatch | 3 | 4 |
| CJNE @Ri,#data,rel | Compare indirect RAM byte vs immediate constant; jump on mismatch | 3 | 4 |
| DJNZ Rn,rel | Decrement Rn register, short jump if result non-zero | 2 | 3 |
| DJNZ Rx,rel | Decrement direct byte, short jump if result non-zero | 3 | 4 |
| NOP | No operation; consume one machine cycle with zero state changes | 1 | 1 |
Conditional branch instructions form the core logic of all security validation subroutines. The JB opcode, for instance, is universally implemented to poll lockbit fuse status bits. If the fuse bit is set to locked state, the CPU branches into a subroutine that disables debug interfaces and blocks external memory read operations. Hardware attackers exploit clock/voltage glitching to corrupt the bit-read sampling logic of JB, forcing the MCU to treat a set lockbit as cleared and bypass protection entirely. Similarly, CJNE comparison opcodes power password and cryptographic key verification loops; precise fault injection mid-comparison manipulates branch outcomes to redirect execution to unprotected firmware read routines. In reverse engineering analysis, mapping the full program branch graph is a mandatory step to locate hidden unlock entry points and patch binary images for locked device data recovery.
Data transfer opcodes copy register and memory contents between storage locations, leaving the source data unmodified post-operation. Variants prefixed with the suffix "X" (MOVX) facilitate bidirectional data exchange with external data memory space.
| Data Transfer Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| MOV A,Rn | Copy value from working register Rn into accumulator A | 1 | 1 |
| MOV A,direct | Copy value from directly addressed byte into accumulator A | 2 | 2 |
| MOV A,@Ri | Copy value from indirectly addressed RAM byte into accumulator A | 1 | 2 |
| MOV A,#data | Load 8-bit immediate constant value directly into accumulator A | 2 | 2 |
| MOV Rn,A | Copy accumulator A value into working register Rn | 1 | 2 |
| MOV Rn,direct | Copy direct byte value into working register Rn | 2 | 4 |
| MOV Rn,#data | Load 8-bit immediate constant into working register Rn | 2 | 2 |
| MOV direct,A | Copy accumulator A value into directly addressed memory/SFR byte | 2 | 3 |
| MOV direct,Rn | Copy working register Rn value into direct byte address | 2 | 3 |
| MOV direct,direct | Copy data between two separate direct byte addresses | 3 | 4 |
| MOV direct,@Ri | Copy indirect RAM byte value into direct byte address | 2 | 4 |
| MOV direct,#data | Load 8-bit immediate constant into direct byte address | 3 | 3 |
| MOV @Ri,A | Copy accumulator A value into indirectly addressed RAM location | 1 | 3 |
| MOV @Ri,direct | Copy direct byte value into indirectly addressed RAM location | 2 | 5 |
| MOV @Ri,#data | Load 8-bit immediate constant into indirect RAM address | 2 | 3 |
| MOV DPTR,#data | Load 16-bit immediate constant into 16-bit data pointer DPTR | 3 | 3 |
| MOVC A,@A+DPTR | Read code Flash memory byte indexed by A + DPTR into accumulator A | 1 | 3 |
| MOVC A,@A+PC | Read code Flash memory byte indexed by A + program counter PC into A | 1 | 3 |
| MOVX A,@Ri | Read 8-bit address external data RAM into accumulator A | 1 | 3-10 |
| MOVX A,@DPTR | Read 16-bit address external data RAM into accumulator A | 1 | 3-10 |
| MOVX @Ri,A | Write accumulator A value to 8-bit address external data RAM | 1 | 4-11 |
| MOVX @DPTR,A | Write accumulator A value to 16-bit address external data RAM | 1 | 4-11 |
| PUSH direct | Push direct byte value onto CPU stack, increment stack pointer SP | 2 | 4 |
| POP direct | Pop top stack value to direct byte, decrement stack pointer SP | 2 | 3 |
| XCH A,Rn | Swap full 8-bit contents of accumulator A and register Rn | 1 | 2 |
| XCH A,direct | Swap full 8-bit contents of A and directly addressed byte | 2 | 3 |
| XCH A,@Ri | Swap full 8-bit contents of A and indirect RAM byte | 1 | 3 |
| XCHD A,@Ri | Exchange only low 4-bit nibble between A and indirect RAM byte | 1 | 3 |
Data transfer opcodes constitute the most frequently executed instructions in all embedded firmware, while simultaneously acting as primary attack surfaces for hardware exploitation. MOVC variants are purpose-built to access program Flash memory space; when lockbit fuses are programmed active, these instructions return corrupted meaningless bytes to block code dumping. However, precise supply voltage glitching during MOVC execution can disrupt memory read protection logic, enabling attackers to extract raw Flash binary byte-by-byte, a mainstream side-channel reverse engineering technique. MOVX opcodes target external data memory buses, which remain unencrypted and easily monitored via logic analyzers to duplicate full firmware without die-level physical attacks. For on-chip EEPROM storage holding serial numbers, calibration data and cryptographic keys, direct MOV read/write instructions access security control SFR registers including lock configuration bits. Accidental leftover debug interfaces in production firmware allow adversaries to use simple MOV sequences to deactivate chip locks and perform complete memory dumps. Stack manipulation opcodes PUSH and POP introduce stack overflow vulnerability vectors; malicious payloads can overwrite stack return addresses to redirect CPU execution to custom subroutines that disable lock protection. During forensic recovery of locked MCUs, analysts trace all MOV instruction sequences to locate undocumented manufacturer backdoors designed for authorized full memory extraction.
Logic instructions perform bitwise mathematical operations on matching individual bits of two 8-bit operands, storing the final computed result within the first operand storage location upon completion.
| Logic Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| ANL A,Rn | Bitwise AND between accumulator A and working register Rn | 1 | 1 |
| ANL A,direct | Bitwise AND between accumulator A and direct memory/SFR byte | 2 | 2 |
| ANL A,@Ri | Bitwise AND between accumulator A and indirectly addressed RAM byte | 1 | 2 |
| ANL A,#data | Bitwise AND between accumulator A and 8-bit immediate constant | 2 | 2 |
| ANL direct,A | Bitwise AND between direct byte and accumulator A, store result to direct byte | 2 | 3 |
| ANL direct,#data | Bitwise AND between direct byte and immediate constant, store result to direct byte | 3 | 4 |
| ORL A,Rn | Bitwise OR between accumulator A and working register Rn | 1 | 1 |
| ORL A,direct | Bitwise OR between accumulator A and direct memory/SFR byte | 2 | 2 |
| ORL A,@Ri | Bitwise OR between accumulator A and indirectly addressed RAM byte | 1 | 2 |
| ORL direct,A | Bitwise OR between direct byte and accumulator A, store result to direct byte | 2 | 3 |
| ORL direct,#data | Bitwise OR between direct byte and immediate constant, store result to direct byte | 3 | 4 |
| XRL A,Rn | Bitwise XOR between accumulator A and working register Rn | 1 | 1 |
| XRL A,direct | Bitwise XOR between accumulator A and direct memory/SFR byte | 2 | 2 |
| XRL A,@Ri | Bitwise XOR between accumulator A and indirectly addressed RAM byte | 1 | 2 |
| XRL A,#data | Bitwise XOR between accumulator A and 8-bit immediate constant | 2 | 2 |
| XRL direct,A | Bitwise XOR between direct byte and accumulator A, store result to direct byte | 2 | 3 |
| XORL direct,#data | Bitwise XOR between direct byte and immediate constant, store result to direct byte | 3 | 4 |
| CLR A | Set all 8 bits of accumulator A to logic 0 | 1 | 1 |
| CPL A | Bitwise invert every bit inside accumulator A (0 ↔ 1) | 1 | 1 |
| SWAP A | Swap upper 4-bit high nibble and lower 4-bit low nibble of accumulator A | 1 | 1 |
| RL A | Rotate all 8 bits of accumulator A left one position, bit7 wraps to bit0 | 1 | 1 |
| RLC A | Rotate accumulator A left through carry flag C, bit7 shifts into C, C shifts into bit0 | 1 | 1 |
| RR A | Rotate all 8 bits of accumulator A right one position, bit0 wraps to bit7 | 1 | 1 |
| RRC A | Rotate accumulator A right through carry flag C, bit0 shifts into C, C shifts into bit7 | 1 | 1 |
Bitwise logic opcodes are primary tools for masking and modifying lockbit fuse registers and security configuration SFRs. The ANL mnemonic selectively clears individual register bits, while ORL selectively sets target bits within configuration memory. Hardware fault injection mid-execution of these instructions can corrupt operand values to unintentionally toggle locked fuse states and fully unlock the microcontroller. The XRL exclusive OR instruction is widely implemented inside firmware obfuscation and lightweight encryption routines; reversing the XOR masking operation allows attackers to recover plaintext security keys stored within on-chip EEPROM. For complete firmware dumping workflows, full comprehension of bitwise arithmetic is mandatory to decrypt protected code segments prior to binary extraction and disassembly.
Bit-oriented opcodes share functional similarities with general logic instructions, but exclusively operate on single independent bit-addressable memory bits rather than full 8-bit bytes.
| Bit-oriented Instructions | |||
|---|---|---|---|
| Mnemonic | Description | Byte | Cycle |
| CLR C | Force carry flag C to logic low value 0 | 1 | 1 |
| CLR bit | Clear specified bit-addressable RAM/SFR bit to logic 0 | 2 | 3 |
| SETB C | Force carry flag C to logic high value 1 | 1 | 1 |
| SETB bit | Set specified bit-addressable RAM/SFR bit to logic 1 | 2 | 3 |
| CPL C | Invert current logic state of carry flag C (0 ↔ 1) | 1 | 1 |
| CPL bit | Invert logic state of single bit-addressable target bit (0 ↔ 1) | 2 | 3 |
| ANL C,bit | Bitwise AND operation between carry flag C and specified RAM bit | 2 | 2 |
| ANL C,/bit | Bitwise AND between carry flag C and inverted state of target RAM bit | 2 | 2 |
| ORL C,bit | Bitwise OR operation between carry flag C and specified RAM bit | 2 | 2 |
| ORL C,/bit | Bitwise OR between carry flag C and inverted state of target RAM bit | 2 | 2 |
| MOV C,bit | Copy logic state of target bit-addressable bit into carry flag C | 2 | 2 |
| MOV bit,C | Copy current logic state of carry flag C into target bit-addressable bit | 2 | 3 |
Bit-manipulation opcodes constitute the primary mechanism for directly modifying lockbit fuses and other security critical status bits. SETB and CLR commands can directly alter lock fuse states, though mainstream 8051 derivative MCUs harden lockbits as read-only under standard runtime execution to block software-based unlocking. Critical firmware bugs occasionally expose write access to lock control registers, enabling remote software unlocking via these bit opcodes. The MOV C,bit instruction retrieves lock fuse status into the carry flag register, which subsequent JC/JNC conditional jumps evaluate to enforce memory access restrictions. This read-then-branch sequence represents a primary target for hardware glitching attacks; flipping the carry flag logic value mid-execution bypasses lock authentication logic entirely. In physical decapsulation reverse engineering workflows, these individual bit storage cells are directly probed under a microscope to read raw fuse lock states, eliminating the requirement for any software exploit to dump full device code memory.
Below is standardized glossary defining every operand notation used across all 8051 instruction syntax:
These standardized operand notations define all valid 8051 addressing modes and serve as critical reference points for locating lockbit fuse addresses within the chip memory map. A standard reverse engineering workflow scans all direct-address opcodes referencing security control SFR memory offsets, then traces every read/write instruction targeting those addresses to uncover hidden manufacturer test interfaces or undocumented backdoors permitting unprotected full memory dumps. For forensic firmware extraction, precise comprehension of each operand classification is mandatory to reconstruct accurate full memory dumps and correctly interpret disassembled binary code recovered from locked microcontrollers.
ACALL addr11 - Absolute subroutine call
addr11: Target 11-bit subroutine memory address
Description: This opcode triggers an unconditional jump to execute a separate subroutine located at the specified 11-bit program memory address. A hard constraint enforces that the current program counter address and the target subroutine address must exist within the identical 2KB contiguous block of Flash memory, measured starting from the first byte of the instruction that follows ACALL.
Syntax: ACALL [subroutine label];
Bytes: 2 (primary opcode byte, 11-bit truncated subroutine address);
STATUS register flags: No PSW status flags are modified or affected during execution.
EXAMPLE:
Register Address SUM=F3
Before execution: SUM=58h R1=F3
After execution: SUM=58h TEMP=58h
MOV direct1,direct2 - Moves the direct byte to the direct byte
```html Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Description: This instruction copies data from one direct-addressable byte to another direct-addressable byte. Since direct addressing is utilized, both source and destination operands can be any Special Function Register (SFR) or general-purpose RAM register located within address range 0x00–0x7F (0–127 decimal). The source operand direct1 retains its original value after execution.
Syntax: MOV direct1,direct2;
Byte Count: 3 (opcode byte, direct1 address byte, direct2 address byte);
STATUS register flags: No status flags are modified.
EXAMPLE:
Pre-execution state: TEMP=0x58
Post-execution state: TEMP=0x58 SUM=0x58
MOV @Ri,A – Copy accumulator data to indirectly addressed internal RAM
A: Accumulator register
Ri: Indirect addressing register, either R0 or R1
Description: The instruction transfers the value stored in the accumulator to the internal RAM location whose address is held inside Ri (R0 or R1). The accumulator’s value remains unchanged upon completion of execution.
Syntax: MOV @Ri,A;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Target RAM address SUM=0xF2h
Pre-execution state: R0=0xF2h A=0x58h
Post-execution state: SUM=0x58h A=0x58h
MOV direct,#data – Load immediate constant value into a direct-addressable byte
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Data: 8-bit constant value between 0 and 255 (0x00 to 0xFF)
Description: This instruction writes an immediate constant value into a direct-addressable byte location. Direct addressing allows the target byte to be any SFR or general-purpose RAM register within address space 0x00–0x7F (0–127 decimal).
Syntax: MOV direct,#data;
Byte Count: 3 (opcode byte, target direct address byte, immediate data byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Post-execution state: TEMP=0x22h
MOV @Ri,#data – Load immediate constant into indirectly addressed internal RAM
Ri: Indirect addressing register R0 or R1
Data: 8-bit constant value between 0 and 255 (0x00 to 0xFF)
Description: The instruction stores an immediate constant value into the internal RAM address pointed to by Ri (R0 or R1).
Syntax: MOV @Ri,#data;
Byte Count: 2 (opcode byte, immediate data byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Target RAM address TEMP=0xE2h
Pre-execution state: R1=0xE2h
Post-execution state: TEMP=0x44h
MOV @Ri,direct – Copy direct byte data to indirectly addressed internal RAM
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Ri: Indirect addressing register R0 or R1
Description: This instruction copies the value of a direct-addressable byte into the internal RAM location whose address is stored within Ri (R0 or R1). The source direct byte retains its original value after operation completes.
Syntax: MOV @Ri,direct;
Byte Count: 2 (opcode byte, source direct address byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Target RAM address TEMP=0xE2h
Pre-execution state: SUM=0x58h R1=0xE2h
Post-execution state: SUM=0x58h TEMP=0x58h
MOV bit,C – Copy carry flag state to a direct bit address
C: Carry flag bit inside PSW register
Bit: Any individually addressable bit of internal RAM
Description: The instruction transfers the logic state of the carry flag to a specified bit-addressable RAM location. The carry flag’s value remains unchanged after execution.
Syntax: MOV bit,C;
Byte Count: 2 (opcode byte, target bit address byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Post-execution rule: If C=0 then P1.2=0
If C=1 then P1.2=1
MOV C,bit – Copy direct bit state into carry flag
C: Carry flag bit inside PSW register
Bit: Any individually addressable bit of internal RAM
Description: This instruction loads the logic value of a specified bit-addressable RAM location into the carry flag. The source bit’s state is preserved after execution finishes.
Syntax: MOV C,bit;
Byte Count: 2 (opcode byte, source bit address byte);
STATUS register flags: Carry flag (C) is updated;
EXAMPLE:
Post-execution rule: If P1.4=0 then C=0
If P1.4=1 then C=1
This instruction reads the lock fuse bit into the carry flag. A voltage or clock glitch that flips the target bit during read operation will corrupt the carry flag value, which may allow attackers to bypass lockout validation logic.
MOVC A,@A+DPTR – Read program memory byte offset by accumulator from DPTR into accumulator
A: Accumulator register
DPTR: 16-bit data pointer register pair (DPH + DPL)
Description: The instruction first calculates the sum of the 16-bit DPTR register value and the 8-bit accumulator value. The resulting 16-bit address points to a byte within program flash memory, which is then loaded into the accumulator register.
Syntax: MOVC A,@A+DPTR;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution states:
DPTR=0x1000:
A=0
A=1
A=2
A=3
Post-execution states:
A=0x66
A=0x77
A=0x88
A=0x99
Note: DB (Define Byte) is an assembly assembler directive used to define static constant byte values inside program memory.
This is the primary opcode used to read program flash memory contents. Locked microcontrollers will return scrambled garbage data when this instruction executes normally, but attackers can inject address bus glitches to force the correct unscrambled byte output, enabling full byte-by-byte dumping of the flash firmware.
MOV DPTR,#data16 – Load 16-bit immediate constant into data pointer register
Data: 16-bit constant value ranging from 0 to 65535 (0x0000 to 0xFFFF)
DPTR: 16-bit data pointer register composed of DPH (high byte) and DPL (low byte)
Description: This instruction stores a 16-bit immediate constant into the DPTR register pair. The upper 8 bits of the constant populate the DPH register, while the lower 8 bits populate the DPL register.
Syntax: MOV DPTR,#data;
Byte Count: 3 (opcode byte, high constant byte bits 15–8, low constant byte bits 7–0);
STATUS register flags: No status flags are altered;
EXAMPLE:
Post-execution state: DPH=0x12 DPL=0x34
MOVX A,@Ri – Read 8-bit address external RAM data into accumulator
Ri: Indirect addressing register R0 or R1
A: Accumulator register
Description: The opcode reads the data stored at an 8-bit address within external RAM and copies it into the accumulator register. The target external RAM address is held inside Ri (R0 or R1).
Syntax: MOVX A,@Ri;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
External RAM Address: SUM=0x12h
Pre-execution state: SUM=0x58h R0=0x12h
Post-execution state: A=0x58h
Note:
The SUM storage location resides within the 256-byte low external RAM address space.
External RAM memory is typically unencrypted and susceptible to bus signal sniffing, allowing adversaries to capture sensitive confidential data without unlocking the microcontroller security locks.
MOVC A,@A+PC – Read program memory byte offset by accumulator from program counter into accumulator
A: Accumulator register
PC: 16-bit program counter register
Description: The instruction computes the sum of the current 16-bit program counter value and the 8-bit accumulator value. The resulting address points to a byte within program flash memory, which is loaded into the accumulator register.
Syntax: MOVC A,@A+PC;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
After executing the subroutine labeled "Table", one of four distinct constant values will be stored in the accumulator register:
Pre-execution accumulator values:
A=0
A=1
A=2
A=3
Post-execution accumulator values:
A=0x66
A=0x77
A=0x88
A=0x99
Note: DB (Define Byte) is an assembly assembler directive used to define static constant byte values inside program memory.
This secondary program memory read instruction shares exploitation vectors with the DPTR-based MOVC variant. If clock or voltage glitches can bypass security lock fuses, attackers can leverage this opcode to fully dump the entire flash firmware image.
MOVX @Ri,A – Write accumulator data to 8-bit address external RAM
Ri: Indirect addressing register R0 or R1
A: Accumulator register
Description: This instruction copies the accumulator’s stored value into an external RAM location whose 8-bit address is stored within Ri (R0 or R1).
Syntax: MOVX @Ri,A;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
External RAM address: SUM=0x34h
Pre-execution state: A=0x58 R1=0x34h
Post-execution state: SUM=0x58h
NOTE:
The SUM storage location is located within the 256-byte low external RAM address space.
MOVX A,@DPTR – Read 16-bit address external RAM data into accumulator
A: Accumulator register
DPTR: 16-bit data pointer register pair (DPH + DPL)
Description: The opcode loads the byte value stored at the 16-bit external RAM address held inside DPTR (DPH contains high address byte, DPL low address byte) into the accumulator register.
Syntax: MOVX A,@DPTR;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
External RAM address: SUM=0x1234h
Pre-execution state: DPTR=0x1234h SUM=0x58
Post-execution state: A=0x58h
Note:
The SUM storage location resides within the full 64KB address space of external RAM.
MUL AB – Unsigned 8-bit multiply of accumulator and B register
A: Accumulator register
B: General-purpose B register
Description: This instruction multiplies the unsigned 8-bit value in the accumulator with the unsigned 8-bit value stored in the B register. The lower 8 bits of the resulting 16-bit product are saved inside the accumulator, while the upper 8 bits are stored inside the B register. If the product value exceeds 255 decimal, the overflow (OV) flag is set; the carry (C) flag remains unaffected.
Syntax: MUL AB;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: A=80 (0x50) B=160 (0xA0)
Post-execution state: A=0x00 B=0x32
Mathematical product: A·B = 80 × 160 = 12800 (0x3200)
MOVX @DPTR,A – Write accumulator data to 16-bit address external RAM
A: Accumulator register
DPTR: 16-bit data pointer register pair (DPH + DPL)
Description: This instruction copies the accumulator’s byte value into the external RAM location addressed by the full 16-bit address stored within DPTR (DPH = high address byte, DPL = low address byte).
Syntax: MOVX @DPTR,A;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
External RAM address: SUM=0x1234h
Pre-execution state: A=0x58 DPTR=0x1234h
Post-execution state: SUM=0x58h
Note:
The SUM storage location resides within the full 64KB address space of external RAM.
ORL A,Rn – Bitwise logical OR between accumulator and working register Rn
Rn: Any working register from R0 through R7
A: Accumulator register
Description: The instruction performs a bitwise logical OR operation between the accumulator value and the value stored in target working register Rn. The resulting bitwise output is written back into the accumulator register.
Syntax: ORL A,Rn;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: A=0xC3 (Binary 11000011)
R5=0x55 (Binary 01010101)
Post-execution state: A=0xD7 (Binary 11010111)
NOP – No operation cycle
Description: This opcode executes no data manipulation or logic operations, and is exclusively used to introduce precise fixed timing delays in code execution flow.
Syntax: NOP;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
The provided assembly sequence generates a negative logic pulse with an exact duration of 5 machine cycles on pin P2.3. When using a 12 MHz crystal oscillator, each machine cycle consumes 1 microsecond, creating a 5 microsecond low-going pulse on this output pin.
ORL A,@Ri – Bitwise logical OR between accumulator and indirectly addressed internal RAM byte
Ri: Indirect addressing register R0 or R1
A: Accumulator register
Description: The instruction executes a bitwise logical OR operation between the accumulator value and the byte stored at the internal RAM address pointed to by Ri (R0/R1 indirect addressing). The resulting bitwise result overwrites the accumulator register value.
Syntax: ANL A,@Ri;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Target indirect RAM address: TEMP=0xFAh
Pre-execution state: R1=0xFAh
TEMP=0xC2 (Binary 11000010)
A=0x54 (Binary 01010100)
Post-execution state: A=0xD6 (Binary 11010110)
ORL A,direct – Bitwise logical OR between accumulator and direct-addressable byte
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
A: Accumulator register
Description: This opcode computes a bitwise logical OR between the accumulator and a direct-addressable byte location. Direct addressing permits the target byte to be any SFR or general-purpose RAM register within address range 0x00–0x7F (0–127 decimal). The bitwise output result is stored back into the accumulator register.
Syntax: ORL A,direct;
Byte Count: 2 (opcode byte, direct target address byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
LOG=0x54 (Binary 01010100)
Post-execution state: A=0xD6 (Binary 11010110)
ORL direct,A – Bitwise logical OR between direct-addressable byte and accumulator, store result to direct byte
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
A: Accumulator register
Description: The instruction performs a bitwise logical OR operation between a direct-addressable byte location and the accumulator register. Direct addressing supports all SFRs and general-purpose RAM registers within address range 0x00–0x7F (0–127 decimal). The computed bitwise result overwrites the original direct byte value.
Syntax: ORL [register address], A;
Byte Count: 2 (opcode byte, direct byte address);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: TEMP=0xC2 (Binary 11000010)
A=0x54 (Binary 01010100)
Post-execution state: A=0xD6 (Binary 11010110)
ORL A,#data – Bitwise logical OR between accumulator and 8-bit immediate constant
Data: 8-bit constant value between 0 and 255 (0x00 to 0xFF)
A: Accumulator register
Description: This opcode executes a bitwise logical OR operation between the accumulator register and an inline immediate constant byte. The resulting bitwise value is saved into the accumulator register.
Syntax: ORL A, #data;
Byte Count: 2 (opcode byte, immediate constant byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
Post-execution state: A=0xC3 (Binary 11000011)
ORL C,bit – Bitwise logical OR between direct bit and carry flag, update carry flag
C: Carry flag bit within PSW register
Bit: Any individually addressable bit of internal RAM
Description: The instruction computes a bitwise logical OR between the logic state of a specified bit-addressable RAM location and the current carry flag value, then writes the resulting single-bit state back into the carry flag register.
Syntax: ORL C,bit;
Byte Count: 2 (opcode byte, target bit address byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: ACC=0xC6 (Binary 11001010)
C=0
Post-execution state: C=1
ORL direct,#data – Bitwise logical OR between direct-addressable byte and immediate constant, store result to direct byte
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Data: 8-bit constant value between 0 and 255 (0x00 to 0xFF)
Description: This opcode performs a bitwise logical OR operation between an immediate constant byte and a direct-addressable memory byte. Direct addressing supports all SFRs and general-purpose RAM registers within address range 0x00–0x7F (0–127 decimal). The computed bitwise output overwrites the original direct byte value.
Syntax: ORL [register address],#data;
Byte Count: 3 (opcode byte, direct byte address, immediate data byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Pre-execution state: TEMP=0xC2 (Binary 11000010)
Post-execution state: A=0xD2 (Binary 11010010)
POP direct – Retrieve stack byte and store to direct-addressable register
Direct: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Description: The instruction first reads the byte data stored at the memory address pointed to by the stack pointer register. This byte value is copied into the specified direct-addressable register, after which the stack pointer register value is decremented by one. Direct addressing allows the target register to be any SFR or general-purpose RAM register within address range 0x00–0x7F (0–127 decimal).
Syntax: POP direct;
Byte Count: 2 (opcode byte, direct byte address);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution memory address map: Address Value
0x30 0x20
0x31 0x23
SP ==> 0x32 0x01
DPTR=0x0123 (DPH=0x01, DPL=0x23)
Post-execution memory address map: Address Value
SP ==> 0x30 0x20
0x31 0x23
0x32 0x01
ORL C,/bit – Bitwise logical OR between inverted direct bit and carry flag, update carry flag
C: Carry flag bit inside PSW register
Bit: Any individually addressable bit of internal RAM
Description: This opcode executes a bitwise logical OR operation between the logical inverse of the target bit-addressable RAM location and the current carry flag value, then writes the resulting single-bit state back into the carry flag register.
| bit raw value | /bit (inverted bit) | C initial value | C = C OR /bit Result |
|---|---|---|---|
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 |
Syntax: ORL C,/bit;
Byte Count: 2 (opcode byte, bit address byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Pre-execution state: ACC=0xC6 (Binary 11001010)
C=0
Post-execution state: C=0
RET – Subroutine return instruction
Description: This opcode terminates execution of every assembly subroutine block. After finishing RET, program execution resumes at the instruction immediately following the prior ACALL or LCALL subroutine call opcode.
Syntax: RET;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
PUSH direct – Store direct-addressable byte onto program stack
Data: General-purpose register with address ranging from 0 to 255 (0x00 to 0xFF)
Description: The stack pointer register value is incremented by one first, then the byte value from the specified direct-addressable register is copied into the stack memory location pointed to by the updated stack pointer. Direct addressing supports all SFRs and general-purpose RAM registers within address range 0x00–0x7F (0–127 decimal).
Syntax: PUSH direct;
Byte Count: 2 (opcode byte, direct byte address);
STATUS register flags: No status flags are altered;
EXAMPLE:
Pre-execution memory address map: Address Value
SP ==> 0x30 0x20
DPTR=0x0123 (DPH=0x01, DPL=0x23)
Post-execution memory address map: Address Value
0x30 0x20
0x31 0x23
SP ==> 0x32 0x01
RL A – Rotate accumulator bits left one position (carry flag excluded)
A: Accumulator register
Description: All eight bits contained within the accumulator register are rotated left by one single bit position. The most significant bit (bit 7) of the accumulator wraps around and becomes the new least significant bit (bit 0).
Syntax: RL A;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
Post-execution state: A=0x85 (Binary 10000101)
RETI – Interrupt service routine return instruction
Description: This opcode terminates every interrupt service subroutine and signals the microcontroller core that interrupt handling has completed. After execution, program flow resumes from the exact instruction location interrupted by the hardware event. The Program Status Word (PSW) register state is not automatically restored to its pre-interrupt value by hardware.
Syntax: RETI;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are altered;
RR A – Rotate accumulator bits right one position (carry flag excluded)
A: Accumulator register
Description: All eight bits inside the accumulator register are rotated right by one single bit position. The least significant bit (bit 0) wraps around and becomes the new most significant bit (bit 7).
Syntax: RR A;
Byte Count: 1 (single opcode byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
Post-execution state: A=0x61 (Binary 01100001)
RLC A – Rotate accumulator left one bit through carry flag
A: Accumulator register
Description: All eight accumulator bits and the single carry flag bit form a collective 9-bit shift register rotated left one position. The accumulator’s MSB (bit7) moves into the carry flag, and the original carry flag bit shifts into the accumulator’s LSB (bit0).
Syntax: RLC A;
Byte Count: 1 (single opcode byte);
STATUS register flags: Carry flag (C) is updated;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
C=0
Post-execution state: A=0x85 (Binary 10000100)
C=1
SETB C – Force carry flag logic state to 1
C: Carry flag bit within PSW register
Description: This opcode sets the carry flag bit to a permanent logic high (1) state.
Syntax: SETB C;
Byte Count: 1 (single opcode byte);
STATUS register flags: Carry flag (C) is set to 1;
EXAMPLE:
Post-execution state: C=1
Modifying the carry flag (SETB C / CLR C) is commonly used to control conditional jump instructions (JC / JNC). In reverse engineering and hardware attack scenarios, adversaries can inject voltage or clock glitches to flip the carry flag mid-execution of conditional branches, forcing the microcontroller to execute an unintended code path that frequently bypasses security lock validation logic. This classic fault injection technique enables device unlocking without requiring full chip decapsulation for physical probing.
RRC A – Rotate accumulator right one bit through carry flag
A: Accumulator register
Description: The eight accumulator bits plus carry flag form a 9-bit shift register rotated right one position. The accumulator’s LSB (bit0) transfers into the carry flag, while the original carry flag bit shifts into the accumulator’s MSB (bit7).
Syntax: RRC A;
Byte Count: 1 (single opcode byte);
STATUS register flags: Carry flag (C) is updated;
EXAMPLE:
Pre-execution state: A=0xC2 (Binary 11000010)
C=0
Post-execution state: A=0x61 (Binary 01100001)
C=0
SJMP rel – Short relative unconditional jump
addr: Relative offset jump target address
Description: This opcode performs an unconditional jump to a target memory address within a relative offset range of -128 to +128 bytes measured from the address of the instruction immediately following the SJMP opcode.
Syntax: SJMP [jump address];
Byte Count: 2 (opcode byte, signed relative offset byte);
STATUS register flags: No status flags are modified;
EXAMPLE:
Pre-execution program counter value: PC=323
Post-execution program counter value: PC=345
SETB bit – Set specified bit-addressable RAM bit to logic 1
Bit: Any individually addressable bit of internal RAM
Description: The opcode forces the selected bit-addressable memory bit into logic high (1). The parent register containing this bit must belong to the subset of bit-addressable SFR and RAM registers defined in the 8051 architecture specification.
Syntax: SETB [bit address];
Byte Count: 2 (opcode byte, target bit address byte);
STATUS register flags: No status flags are altered;
EXAMPLE:
Before execution: P0.1 = 34h (00110100)
Pin 1 is configured as an output
After execution: P0.1 = 35h (00110101)
Pin 1 is configured as an input
The SETB bit instruction serves as the inverse operation of the CLR bit instruction. While it is widely adopted for general-purpose pin configuration, it also introduces potential security vulnerabilities if attackers can leverage it to alter lockbit states. Nevertheless, most 8051-based microcontrollers implement hardware restrictions that block software from modifying lockbits, limiting this instruction’s risks to non-security-critical bit registers. In scenarios where firmware contains unpatched bugs, malicious actors may exploit SETB to activate undocumented factory test modes, which grant full read access to the on-chip Flash program memory.
SUBB A,direct – Subtract the direct-address byte from the Accumulator with borrow input
Direct: Any general-purpose or special-function register with an address range of 0 to 255 (00h to FFh)
A: Accumulator register
Description: This instruction performs a subtraction operation between the Accumulator and a direct-address memory byte, incorporating the carry borrow flag into the calculation. A carry flag (C) will be asserted if a higher-order bit must borrow from a lower-order bit during subtraction. As a direct addressing operation, the target byte can reference any SFR or general-purpose RAM register within the 0–7Fh (0–127 decimal) address space. The final arithmetic result is stored inside the Accumulator register.
Syntax: SUBB A,direct;
Instruction Byte Count: 2 (opcode byte + direct address byte);
Affected STATUS Register Flags: C, OV, AC;
EXAMPLE:
Before execution: A=C9h, DIF=53h, C=0
After execution: A=76h, C=0
SUBB A,Rn – Subtract the working register Rn value from the Accumulator with borrow input
Rn: Any working register from R0 through R7
A: Accumulator register
Description: This instruction subtracts the 8-bit value stored in the selected Rn working register from the Accumulator, factoring in the existing carry borrow flag. The carry flag C will be set when a borrow is required across bit boundaries during subtraction. The resulting 8-bit value is written back to the Accumulator register.
Syntax: SUBB A,Rn;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: C, OV, AC;
EXAMPLE:
Before execution: A=C9h, R4=54h, C=1
After execution: A=74h, C=0
Note:
The mathematical result differs from the raw calculation C9 − 54 = 75 because the carry flag C is asserted (C=1) prior to instruction execution, which deducts an additional borrow value from the subtraction total.
SUBB A,#data – Subtract an immediate 8-bit constant from the Accumulator with borrow input
A: Accumulator register
Data: Static 8-bit constant ranging from 0 to 255 (00h to FFh)
Description: This instruction subtracts a hardcoded immediate byte value from the Accumulator, including the carry borrow flag in the arithmetic operation. The carry flag C is raised whenever a bit-level borrow occurs during subtraction. The computed result is stored within the Accumulator register.
Syntax: SUBB A,#data;
Instruction Byte Count: 2 (opcode byte + immediate data byte);
Affected STATUS Register Flags: C, OV, AC;
EXAMPLE:
Before execution: A=C9h, C=0
After execution: A=A7h, C=0
SUBB A,@Ri – Subtract indirectly addressed internal RAM data from the Accumulator with borrow input
Ri: Indirect addressing pointer register, either R0 or R1
A: Accumulator register
Description: This instruction retrieves an 8-bit value from internal RAM using indirect addressing via Ri, then subtracts this value from the Accumulator while accounting for the carry borrow flag. If a cross-bit borrow is needed during subtraction, the carry flag C will be set. The target RAM address is held inside the Ri pointer register (R0 or R1). The final subtraction result is saved to the Accumulator register.
Syntax: SUBB A,@Ri;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: C, OV, AC;
EXAMPLE:
Target RAM address label: MIN=F4h
Before execution: A=C9h, R1=F4h, MIN=04h, C=0
After execution: A=C5h, C=0
XCH A,Rn – Swap data contents between the Accumulator and a working register Rn
Rn: Any working register R0 through R7
A: Accumulator register
Description: This instruction performs a full byte swap operation between the Accumulator and the specified Rn working register. The 8-bit value stored in the Accumulator is copied to Rn, and simultaneously the original value of Rn is loaded into the Accumulator register.
Syntax: XCH A,Rn;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A=C6h, R3=29h
After execution: R3=C6h, A=29h
SWAP A – Exchange high and low 4-bit nibbles within the Accumulator register
A: Accumulator register
Description: A nibble refers to a 4-bit segment of an 8-bit byte, split into low nibble (bits 0–3) and high nibble (bits 4–7). This instruction swaps the positions of the high-order and low-order nibbles entirely inside the Accumulator register.
Syntax: SWAP A;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A=E1h (binary 11100001).
After execution: A=1Eh (binary 00011110).
XCH A,@Ri – Swap byte data between the Accumulator and indirectly addressed internal RAM
Ri: Indirect pointer register R0 or R1
A: Accumulator register
Description: This instruction exchanges the full byte contents of the Accumulator with an internal RAM location targeted via indirect addressing. The RAM address to be accessed is stored inside the Ri pointer register (either R0 or R1).
Syntax: XCH A,@Ri;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Target RAM address label: SUM=E3h
Before execution: R0=E3h, SUM=29h, A=98h
After execution: A=29h, SUM=98h
XCH A,direct – Swap byte data between the Accumulator and a direct-address register byte
Direct: Any register/SFR with address range 0 to 255 (00h to FFh)
A: Accumulator register
Description: This instruction swaps the full 8-bit value held in the Accumulator with the value stored at a direct-address memory location. Direct addressing supports access to any SFR or general-purpose RAM register within the 0–7Fh (0–127 decimal) address range.
Syntax: XCH A,direct;
Instruction Byte Count: 2 (opcode byte + direct address byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A=FFh, SUM=29h
After execution: SUM=FFh, A=29h
XRL A,Rn – Perform bitwise XOR operation between Accumulator and working register Rn
Rn: Any working register R0 through R7
A: Accumulator register
Description: This instruction executes a bitwise exclusive-OR logic operation between the Accumulator and the selected Rn register. The resulting 8-bit XOR value is overwritten into the Accumulator register.
Syntax: XRL A,Rn;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A= C3h (Binary 11000011)
R3= 55h (Binary 01010101)
After execution: A= 96h (Binary 10010110)
XCHD A,@Ri – Swap only low-order 4-bit nibbles between Accumulator and indirectly addressed RAM
Ri: Indirect pointer register R0 or R1
A: Accumulator register
Description: This instruction exchanges solely the low-order nibbles (bits 0–3) of the Accumulator and the indirectly addressed internal RAM byte. The high-order 4-bit nibbles of both the Accumulator and target RAM location remain unchanged. This operation is primarily utilized for BCD arithmetic processing. The target RAM address is stored within the Ri pointer register (R0 or R1).
Syntax: XCHD A,@Ri;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Target RAM address label: SUM=E3h
Before execution: R0=E3h SUM=29h A=A8h,
After execution: A=A9h, SUM=28h
XRL A,@Ri – Perform bitwise XOR between Accumulator and indirectly addressed internal RAM data
Ri: Indirect pointer register R0 or R1
A: Accumulator register
Description: This instruction computes a bitwise exclusive-OR between the Accumulator and the value stored at an indirectly addressed internal RAM location. The RAM address is held in the Ri pointer register (R0 or R1). The final XOR result is written back to the Accumulator register.
Syntax: XRL A,@Ri;
Instruction Byte Count: 1 (single opcode byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Target RAM address label: TEMP=FAh, R1=FAh
Before execution: TEMP= C2h (Binary 11000010)
A= 54h (Binary 01010100)
After execution: A= 96h (Binary 10010110)
XRL A,direct – Execute bitwise XOR between Accumulator and direct-address register byte
Direct: Any register/SFR with address range 0 to 255 (00h to FFh)
A: Accumulator register
Description: This instruction runs a bitwise exclusive-OR calculation using the Accumulator and a direct-address memory byte. Direct addressing enables access to any SFR or general-purpose RAM register within the 0–7Fh (0–127 decimal) address range. The computed XOR result is stored in the Accumulator register.
Syntax: XRL A,direct;
Instruction Byte Count: 2 (opcode byte + direct address byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A= C2h (Binary 11000010)
LOG= 54h (Binary 01010100)
After execution: A= 96h (Binary 10010110)
XRL direct,A – Execute bitwise XOR between direct-address register byte and Accumulator
Direct: Any register/SFR with address range 0 to 255 (00h to FFh)
A: Accumulator register
Description: This instruction performs a bitwise exclusive-OR operation combining a direct-address memory byte and the Accumulator value. Direct addressing supports all SFRs and general-purpose RAM registers in the 0–7Fh address space. The resulting XOR value is saved into the direct-address target register instead of the Accumulator.
Syntax: XRL direct,A;
Instruction Byte Count: 2 (opcode byte + direct address byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: TEMP= C2h (Binary 11000010)
A= 54h (Binary 01010100)
After execution: TEMP= 96h (Binary 10010110)
XRL A,#data – Perform bitwise XOR between Accumulator and an immediate 8-bit constant
Data: Static 8-bit constant from 0 to 255 (00h to FFh)
A: Accumulator register
Description: This instruction computes a bitwise exclusive-OR between the Accumulator and a hardcoded immediate byte value. The output of the XOR logic is stored within the Accumulator register.
Syntax: XRL A,#data;
Instruction Byte Count: 2 (opcode byte + immediate data byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: A= C2h (Binary 11000010)
X= 11h (Binary 00010001)
After execution: A= D3h (Binary 11010011)
XRL direct,#data – Execute bitwise XOR between direct-address register byte and immediate constant
Direct: Any register/SFR with address range 0 to 255 (00h to FFh)
Data: Static 8-bit constant from 0 to 255 (00h to FFh)
Description: This instruction calculates a bitwise exclusive-OR between an immediate constant value and a direct-address memory byte. Direct addressing grants access to all SFRs and general-purpose RAM registers within the 0–7Fh address range. The XOR result is written to the direct-address target register location.
Syntax: XRL direct,#data;
Instruction Byte Count: 3 (opcode byte + direct address byte + immediate data byte);
Affected STATUS Register Flags: No flags modified;
EXAMPLE:
Before execution: TEMP= C2h (Binary 11000010)
X=12h (Binary 00010010)
After execution: TEMP= D0h (Binary 11010000)
More than two decades have elapsed since the original release of the foundational 8051 microcontroller core. Throughout this timeframe, the architecture has undergone extensive iterative upgrades and functional enhancements. Today, dozens of semiconductor manufacturers worldwide produce compatible derivative microcontroller variants marketed under distinct product part numbers. Modern upgraded iterations deliver vastly expanded feature sets compared to the original baseline 8051 design. Most of these derivatives carry labeling such as "8051 compatible", "8051 compliant", or "8051 family" to highlight their shared architectural lineage. These labels signify identical core CPU architectures and uniform programming models utilizing the standard 8051 instruction set. In practical development workflows, proficiency with a single device within this family enables seamless migration to any other compatible model, granting engineers access to hundreds of distinct microcontroller SKUs.
This chapter focuses on the Atman-manufactured AT89S8253 microcontroller as a representative family member. This specific device was selected for detailed analysis due to its widespread industrial adoption, low unit cost, and integrated Flash program memory. The Flash storage characteristic makes it ideal for prototyping and iterative testing, as program images can be repeatedly erased and re-flashed thousands of times. Additionally, its built-in SPI serial programming interface allows firmware re-flashing even after the chip has been permanently soldered onto end-product circuit boards.
However, this convenient in-circuit programmability introduces critical firmware security exposure risks. If the device’s hardware lockbits remain unprogrammed, the full contents of Flash program memory can be externally read out via the SPI programming interface. Atmel integrated a three-tier hardware program memory lock mechanism to block unauthorized external firmware extraction. Nevertheless, hardware security fuses are not invulnerable to circumvention, regardless of microcontroller vendor. Malicious reverse engineers have successfully deployed chip decapsulation and microprobe attacks to bypass lockbit protections and recover complete binary firmware images. In certain exploitation scenarios, the on-chip EEPROM partition – which stores confidential calibration parameters, serial identifiers, and cryptographic keys – can be fully dumped using the MOVX instruction when the EEMEN control bit is enabled. This inherent vulnerability underscores the necessity for embedded developers to fully comprehend the AT89S8253’s native security mechanisms when designing products requiring robust firmware confidentiality and integrity guarantees.
The AT89S8253 also integrates a hardware watchdog timer module that can be configured to detect tampering events and trigger an immediate full system reset. Proper watchdog configuration serves as an anti-extraction countermeasure: if an attacker attempts to halt CPU execution to perform bus probing or memory dumping, the watchdog timeout will force a device reset and interrupt data recovery attempts. Even so, adversaries may exploit clock glitching attacks or direct manipulation of watchdog control SFR registers to disable the timer, provided those registers remain unprotected by lockbit restrictions. Combined deployment of lockbit fuses and watchdog reset logic establishes a multi-layered hardware security barrier that increases the complexity and cost of device cloning and reverse engineering. As observed across all 8051-family microcontrollers, no single hardware security primitive offers absolute protection. Full firmware recovery typically requires combining multiple attack methodologies, including electromagnetic side-channel analysis, voltage/fault injection glitching, and full silicon decapsulation to expose internal security fuses and memory cells. Both embedded security defenses and malicious extraction techniques continue to evolve alongside mainstream industrial microcontroller deployment.
The AT89S8253 semiconductor die is packaged within three standard industry form factors:
The physical packaging form factor directly impacts the difficulty of destructive decapsulation attacks. Larger packages with increased exposed silicon surface area (such as DIP and PLCC) are significantly easier for adversaries to dissect and microprobe than compact TQFP surface-mount packages. Regardless of packaging variant, hardware lockbits remain the primary line of defense against external firmware dumping via the programming interface. Industry best practices mandate programming the highest available lock security tier to disable all SPI read-back commands. Many hardware design teams further harden devices by permanently disabling the SPI programming pin circuitry after mass production to raise the barrier against unauthorized firmware extraction attempts.
VCC Main positive power supply input (4V to 6V DC operating range)
GND System electrical ground reference (negative power supply rail)
Port 0 (P0.0–P0.7) When configured as digital outputs, each pin can drive up to 8 standard TTL logic input loads. When set to input mode, Port 0 pins operate as high-impedance floating inputs with undefined voltage levels relative to system ground. When external data or program memory expansion is implemented, Port 0 serves as the multiplexed address/data bus. The ALE control pin signal dictates whether address or data values are transmitted across the Port 0 bus lines.
Port 1 (P1.0–P1.7) In output configuration, each Port 1 pin can drive up to 4 TTL input loads. When configured as inputs, these pins act as standard TTL-compatible inputs with internal weak pull-up resistors tied to the VCC 5V supply rail. Every Port 1 pin also features dedicated secondary alternate peripheral functions, listed in the table below:
| Port Pin Identifier | Alternate Peripheral Function |
|---|---|
| P1.0 | T2 (Timer 2 external counter input) |
| P1.1 | T2EX (Timer 2 external trigger control input) |
| P1.4 | SS (SPI peripheral slave select control signal) |
| P1.5 | MOSI (SPI master output / slave input data line) |
| P1.6 | MISO (SPI master input / slave output data line) |
| P1.7 | SCK (SPI synchronous serial clock signal) |
Port 2 (P2.0–P2.7) Port 2 electrical characteristics match Port 1 for both input and output operational modes. When external memory expansion is utilized, Port 2 outputs the high 8-bit byte of the 16-bit memory address bus (A8–A15) for target memory addressing.
Port 3 (P3.0–P3.7) Port 3 shares identical general-purpose input/output functionality with Port 1, and each pin implements dedicated secondary peripheral alternate functions detailed later within this chapter.
| Port Pin Identifier | Alternate Peripheral Function |
|---|---|
| P3.0 | RXD (UART serial receive data input) |
| P3.1 | TXD (UART serial transmit data output) |
| P3.2 | INT0 (External hardware interrupt 0 trigger input) |
| P3.3 | INT1 (External hardware interrupt 1 trigger input) |
| P3.4 | T0 (Timer 0 external event counter input) |
| P3.5 | T1 (Timer 1 external event counter input) |
| P3.6 | WR (External data memory write strobe control signal) |
| P3.7 | RD (External data memory read strobe control signal) |
RST A logic-high (digital 1) voltage level applied to this pin triggers a full microcontroller hardware reset sequence.
ALE/PROG During standard runtime operation, the ALE pin generates a continuous clock pulse signal at a frequency equal to 1/16 of the main oscillator frequency, usable for external timing and clock generation circuits. When external memory expansion is active, the ALE signal latches the low 8-bit address byte (A0–A7) transmitted over Port 0. During Flash in-system programming operations, this pin also acts as a dedicated programming control input line.
PSEN This pin outputs an active-low strobe signal exclusively used to access external off-chip program ROM memory devices.
EA/VPP Tying this pin directly to system ground forces the CPU to fetch all program instructions from external off-chip program memory. For standard embedded applications utilizing the on-chip Flash program memory (the most common deployment scenario), this pin must be connected to the positive VCC supply rail. During high-voltage Flash programming cycles, this pin receives a +12V programming bias voltage.
XTAL 1 Internal oscillator circuit input pin. This terminal interfaces with external crystal oscillator components or external precision clock signal sources for synchronous CPU operation.
XTAL 2 Internal oscillator circuit output pin. This pin remains unused when an external standalone clock signal is supplied to XTAL1.
The 12 Kilobyte program memory bank is implemented using floating-gate Flash semiconductor technology, enabling repeated firmware erase and re-programming cycles. All program binary images are written to Flash via the on-board integrated SPI serial peripheral interface. External off-chip program ROM memory expansion is supported as an optional hardware extension, though the native 12KB Flash capacity satisfies the majority of embedded application requirements without additional external memory hardware.
From a hardware security threat perspective, the on-chip Flash program memory represents the primary target for unauthorized firmware recovery attacks. Properly programmed lockbit fuses block all external read-back commands transmitted through the SPI programming interface. However, physical access to the packaged chip enables costly but proven decapsulation attacks that strip away protective epoxy packaging to expose the silicon die, allowing direct electrical microprobing of individual Flash memory storage cells. To mitigate this high-cost physical attack vector, Atmel implemented three hierarchical lock security tiers, yet all hardware fuse-based protection schemes remain susceptible to advanced reverse engineering laboratory equipment and techniques.
The internal volatile RAM space is partitioned into three discrete 128-byte memory blocks, adhering strictly to the original standard 8051 memory layout specification:
EEPROM is a hybrid non-volatile storage medium combining the random read/write flexibility of RAM with the persistent data retention characteristic of ROM. Data written to EEPROM remains stored indefinitely without continuous power supply to the microcontroller. The AT89S8253 integrates a total of 2 Kilobytes (2048 individual byte locations) of dedicated on-chip EEPROM storage.
This EEPROM partition is conventionally utilized to store device unique serial numbers, factory calibration coefficients, and confidential cryptographic security keys. Successful unauthorized read-out of the EEPROM partition exposes all sensitive embedded secret data stored within. While hardware lockbits also restrict external SPI-based EEPROM read operations, this storage bank remains vulnerable to electromagnetic side-channel leakage analysis and voltage fault injection glitching attacks. In specific exploit scenarios, full EEPROM memory dumps can be executed using the MOVX external memory instruction sequence when the EEMEN control bit within the EECON SFR is asserted, creating a well-documented hardware backdoor vulnerability for malicious firmware extraction.
All external program and data memory expansion rules defined for the baseline 8051 core fully apply to the AT89S8253 microcontroller. Both program ROM and data RAM can be expanded using external semiconductor memory chips with a maximum addressable capacity of 64 Kilobytes each. The 16-bit memory addressing mechanism operates identically to the standard original 8051 architecture.
Consistent with all standard 8051-compatible microcontrollers, two distinct memory addressing modes are implemented within the CPU instruction set:
Comprehensive understanding of these two addressing modes is critical for embedded security defense design. Indirect addressing mechanisms present a prominent exploitation vector: if an attacker corrupts the pointer value stored within R0/R1 indirect addressing registers, they can redirect memory read operations to access protected memory regions that are normally blocked via direct addressing restrictions. This class of memory corruption exploits is frequently leveraged to extract locked firmware binaries when direct memory access is blocked by hardware lock fuses.
The AT89S8253 incorporates a total of 40 unique Special Function Registers. To maintain full backward compatibility with legacy 8051 microcontroller generations, the core set of 22 fundamental system registers retains identical memory addresses and functional behavior across all family variants. The remaining supplementary SFRs were added to provide control over the AT89S8253’s extended peripheral hardware modules introduced in this upgraded derivative design.
As visualized in the SFR memory map diagram, every register is assigned a unique fixed RAM address offset. Unused reserved address slots are allocated for future silicon revision upgrades and must never be utilized for user-defined variable storage. As their naming implies, each SFR governs the operation of a dedicated hardware peripheral subcircuit including timers, UART, and SPI interfaces, all of which receive dedicated detailed coverage later in this chapter. This section only reviews core system-wide SFR registers that control multiple independent hardware modules simultaneously.
Among all extended SFR peripherals, the EECON EEPROM control register represents the most security-relevant peripheral control block, as it governs all read/write access permissions to the internal EEPROM non-volatile storage bank. An adversary capable of asserting the EEMEN bit within EECON can utilize the MOVX instruction sequence to fully dump the entire EEPROM address space, effectively bypassing hardware lockbit protections entirely. This unpatched hardware design flaw is a well-documented critical weakness present across multiple 8051 derivative microcontroller variants. Similarly, the WDTCON watchdog timer control register governs tamper detection reset logic; however, attackers may disable watchdog counter operation via precise clock glitching or direct SFR register writes if the watchdog control registers remain unprotected by lock restrictions. Hardware lockbit fuses and watchdog timeout reset logic operate as complementary multi-layer security barriers designed to raise the complexity of device cloning and firmware reverse engineering. Unfortunately, no single hardware security primitive delivers absolute tamper resistance, as silicon decapsulation can expose and physically alter security fuse states to neutralize lock protections. This critical limitation has driven the development of modern secure microcontroller hardware integrating active metal shielding and dedicated tamper detection sensor circuits.
The Accumulator, referenced via the labels ACC or shorthand A, is a foundational core register inherent to all 8051-family microcontroller CPU cores. No internal hardware modifications alter the fundamental byte-wide data storage functionality of this register.
The B register also constitutes a core standard 8051 CPU register with unmodified bitwise operation characteristics. This register exclusively serves as secondary operand storage during 8-bit multiplication (MUL) and division (DIV) arithmetic instruction execution cycles.
The Program Status Word register is a core mandatory 8051 SFR with unaltered flag bit definitions and operational behavior.
The Stack Pointer register is a core standard 8051 SFR with fixed unmodified bitwise functionality.
Each individual bit within these four port registers directly corresponds to one physical I/O pin sharing the same numeric identifier. These registers facilitate bidirectional data transfer between CPU internal logic and external circuit hardware by shifting byte values out to port pins or latching incoming pin voltage levels back into register memory. All four port registers belong to the baseline 8051 core SFR set with unmodified native bit functionality.
The eight working registers R0–R7 form part of the standard 8051 core memory layout with unmodified bit storage behavior.
The AUXR auxiliary SFR contains only two functional user-modifiable control bits:
Data pointers are not physical hardware registers. They are composed of two separate 8-bit registers: DPH (Data Pointer High Byte) and DPL (Data Pointer Low Byte). The full 16-bit width of the data pointer is used to address external RAM and the internal on-chip EEPROM. The DPS bit inside the EECON special function register selects which pair of pointer registers will be active for memory addressing operations:
DPS=0 - The active 16-bit data pointer is formed by DP0L and DP0H, referred to as DPTR0.
DPS=1 - The active 16-bit data pointer is formed by DP1L and DP1H, referred to as DPTR1.
The dual data pointer switching feature delivers convenient runtime address switching, yet it expands the MCU’s attack surface. An adversary with the ability to manipulate the DPS bit can redirect EEPROM read/write accesses to arbitrary memory offsets, potentially exposing security lock bits and protection fuses. In hardware reverse engineering workflows, this pointer switching mechanism is commonly abused to dump security configuration bytes that govern memory lock protection.
This microcontroller integrates 2 KB of non-volatile on-chip EEPROM, designed to store runtime-generated data that must persist through power loss. All values written to the EEPROM retain their state after power is disconnected, with a rated minimum endurance of 100,000 erase-write cycles. Configuration of the EEPROM interface is simplified via a small set of dedicated control bits within the EECON register.
All EEPROM read and write transactions are governed by the EECON special function register. Single-byte EEPROM programming has a relatively slow latency of approximately 4 milliseconds per byte, so a hardware buffer acceleration mechanism is implemented to boost bulk write throughput. When the EELD bit in EECON is asserted, outgoing data is buffered into a 32-byte temporary memory instead of being immediately committed to the EEPROM array. Once EELD is cleared, the subsequent single write operation will flush the full contents of the buffer to physical EEPROM cells alongside the new byte. This batch operation reduces the total write latency for 32 bytes from 128 ms (32 × 4 ms) to a single 4 ms programming cycle.
The EEPROM memory space shares the same addressing pipeline as external data RAM. For this reason, the standard external memory access instruction MOVX is reused to perform both EEPROM and external RAM read/write operations. The EEMEN control bit within EECON determines the target memory space for MOVX operations: external RAM or internal EEPROM. If the target address exceeds the 2 KB EEPROM boundary while EEMEN is active, the hardware automatically routes the access to external memory instead.
While this unified memory access scheme improves development flexibility, it introduces a critical security vulnerability. If an attacker gains the capability to set the EEMEN bit to logic 1, they can leverage MOVX instructions to directly read and overwrite the internal EEPROM contents, fully bypassing memory lock protections. This necessitates write protection for the EECON register after the device lock bits are activated. Many embedded developers overlook this protection step, leaving the EECON register accessible to runtime modification and making the MCU vulnerable to full firmware extraction attacks.
Each bit field within the EECON register controls distinct operational behaviors of the integrated EEPROM module:
WRTINH
The WRTINH bit is read-only. When the supply voltage drops below the minimum threshold required for reliable EEPROM programming, hardware automatically clears this flag, blocking new write cycles and aborting any in-progress programming operations.
RDY/BSY
The RDY/BSY bit functions as a read-only status flag:
DPS
EEMEN
The EEMEN bit represents the primary attack vector for unauthorized EEPROM dumping. Any adversary capable of asserting this bit can execute sequential MOVX read cycles to extract the full EEPROM dataset, including serial identifiers, cryptographic secret keys, and device security configuration parameters. This bit is a primary target during locked-device reverse engineering. Hardware mitigation requires permanent lockbit configuration to block all writes to the EECON register, yet many product implementations omit this safeguard. Recovering proprietary device secrets frequently relies on exploiting this unprotected bit to read protected non-volatile memory regions.
EEMWE
When asserted, the EEMWE bit enables write access to the EEPROM array via MOVX instructions. Software must explicitly clear this flag immediately following the completion of every EEPROM write transaction.
EELD
Asserting the EELD bit activates the 32-byte batch write buffer for accelerated bulk EEPROM programming. While EELD remains high, MOVX write commands populate the temporary hardware buffer rather than committing data directly to EEPROM cells. Developers must clear EELD before transmitting the final data byte in a batch sequence. Execution of the concluding MOVX operation triggers an automatic hardware flush of the entire buffer into physical EEPROM memory over a single 4 ms programming window.
The EELD buffered write mechanism delivers substantial performance gains for multi-byte storage operations, yet it introduces a fault injection vulnerability. Attackers who can inject precise clock or voltage glitches to disrupt the EELD clearing sequence may induce incomplete, partial EEPROM writes. This inconsistent memory state can be exploited to bypass device lock protections, forming the basis of advanced combined timing and hardware fault injection attack methodologies.
The watchdog timer derives its clock signal from the main crystal oscillator. It defaults to a disabled state after system reset and automatically halts counting during Power Down low-power mode, exerting no influence over normal program flow while inactive. Once enabled, the watchdog continuously increments its internal counter; upon overflow, the hardware triggers a full microcontroller reset, restarting program execution from the initial reset vector address. The watchdog reset condition signals abnormal, stalled, or corrupted firmware execution. Developers implement periodic watchdog refresh instructions at key points in application code to prevent unintended resets. All watchdog timer configuration and runtime behavior is managed through individual bit fields within the WDTCON special function register.
Three dedicated prescaler control bits (PS2, PS1, PS0) set the watchdog’s core functional parameter: the nominal overflow timeout interval, which defines the full counter cycle length before reset activation.
The timeout values listed in the following table apply exclusively when the system crystal oscillator operates at 12 MHz.
| Prescaler Bits | Nominal Time | ||
|---|---|---|---|
| PS2 | PS1 | PS0 | |
| 0 | 0 | 0 | 16ms |
| 0 | 0 | 1 | 32ms |
| 0 | 1 | 0 | 64ms |
| 0 | 1 | 1 | 128ms |
| 1 | 0 | 0 | 256ms |
| 1 | 0 | 1 | 512ms |
| 1 | 1 | 0 | 1024ms |
| 1 | 1 | 1 | 2048ms |
PS2,PS1,PS0
These three bits configure the watchdog prescaler and determine the nominal overflow timeout window. If application code fails to clear the WSWRST refresh flag within this interval, the watchdog counter overflows and asserts a full MCU reset. When all three prescaler bits are cleared to zero, the watchdog timeout equals 16,000 machine cycles; when all three bits are set to logic one, the timeout extends to 2,048,000 machine cycles.
WDIDLE
The WDIDLE bit toggles watchdog counting activity during Idle low-power mode:
DISRTO
The DISRTO bit controls whether watchdog-initiated resets drive an external logic signal on the RST hardware pin to reset connected peripheral circuitry:
HWDT
The HWDT bit selects between hardware-locked and software-controllable watchdog operating modes:
WSWRST
Asserting the WSWRST flag refreshes and resets the watchdog counter when the timer operates in software mode (HWDT=0). Application software must clear this bit periodically to maintain uninterrupted MCU operation. Once WSWRST is set, hardware automatically zeros the watchdog counter and self-clears the WSWRST flag.
Writing to the WSWRST bit produces no functional effect on watchdog counting when the timer is running in hardware mode (HWDT=1).
WDTEN
The WDTEN bit enables or disables the watchdog timer exclusively during software mode operation (HWDT=0):
When the watchdog is locked into hardware mode (HWDT=1), the WDTEN bit becomes read-only, reflecting the current active/inactive state of the watchdog counter.
The WDTEN bit only toggles activation state and does not reset the watchdog counter value. The counter retains its current count value as long as WDTEN remains cleared to logic zero.
From a security engineering perspective, the watchdog timer serves as a countermeasure against memory dumping and probing attacks. If an adversary attempts to halt the microcontroller core to read internal memory contents, an active watchdog will force an immediate chip reset, eliminating opportunities for complete, clean memory extraction. However, attackers gain sufficient time to perform full read-out operations if the watchdog is disabled or configured with an excessively long timeout window. Secure firmware design practices mandate configuring the watchdog with a short nominal timeout and enabling hardware lock mode, which blocks software-level watchdog deactivation to hinder unauthorized firmware extraction attempts.
The AT89S8253 microcontroller implements six distinct hardware interrupt sources, allowing the core to pause regular program execution to service six unique asynchronous events. Each individual interrupt channel can be independently masked or unmasked using dedicated bits within the IE (Interrupt Enable) special function register, while the entire global interrupt system can be fully disabled by clearing the EA global enable bit inside the same IE register.
This device integrates Timer T2 and SPI peripheral modules, which extend beyond the standard original 8051 architecture and each generate dedicated interrupt requests. These peripherals required minor modifications to the interrupt control register layout, alongside a new dedicated interrupt vector address at 0x2B for Timer T2 overflow/capture events. All architectural changes reuse previously unused reserved bit positions within existing SFRs, ensuring full backward compatibility with legacy 8051 firmware without source code modifications. This backwards compatibility is a primary factor behind the widespread industry adoption of 8051-based microcontroller families.
The EA bit acts as a global master switch for all interrupt request sources:
The ET2 bit controls masking for Timer T2 interrupt events:
The ES bit enables or disables combined serial communication interrupts for UART and SPI peripherals:
The ET1 bit controls Timer T1 interrupt masking:
The EX1 bit governs external interrupt signals received on the INT1 hardware pin:
The ET0 bit enables or disables Timer T0 overflow interrupts:
The EX0 bit controls external interrupt requests arriving on the INT0 hardware pin:
Interrupt service routines can be implemented as hardware tamper detection countermeasures. For example, an external interrupt tied to the INT0 pin can monitor sudden supply voltage fluctuations indicative of physical tampering. Upon interrupt trigger, the MCU can immediately erase sensitive cryptographic data before adversaries complete full memory read-out operations. However, attack actors who gain the ability to globally disable interrupts or manipulate interrupt priority levels can neutralize these tamper response security routines entirely.
When multiple interrupt channels are simultaneously enabled, a new interrupt request may assert while another interrupt service routine is already executing. The microcontroller’s priority resolution logic determines whether to preempt the active interrupt handler or queue the incoming request for later servicing. Base-generation 8051 microcontrollers provide two fixed interrupt priority levels configured via the IP special function register.
The AT89S8253 extends the standard priority scheme with an additional IPH (Interrupt Priority High) SFR, supporting four distinct programmable interrupt priority tiers for all interrupt sources (excluding the non-maskable hardware reset signal). The global priority hierarchy follows this ordering:
Firmware typically configures each interrupt source’s assigned priority level at the start of the main application code. The hardware enforces the following priority resolution rules during concurrent interrupt requests:
Each bit field within the IP register sets the low-order priority bit for its corresponding interrupt channel.
PT2 – Timer T2 interrupt priority low bit:
PS – Serial port interrupt priority low bit:
PT1 – Timer T1 interrupt priority low bit:
PX1 – External INT1 interrupt priority low bit:
PT0 – Timer T0 interrupt priority low bit:
PX0 – External INT0 interrupt priority low bit:
PT2H Timer T2 interrupt high priority bit
PSH Serial port interrupt high priority bit
PT1H Timer T1 interrupt high priority bit
PX1H External INT1 interrupt high priority bit
PT0H Timer T0 interrupt high priority bit
PX0H External INT0 interrupt high priority bit
Each bit inside the IPH register combines with the matching bit position in the IP register to generate a two-bit priority value, creating four unique interrupt priority tiers (five total tiers when hardware reset is included).
| IP bit Value | IPH bit Value | Assigned Interrupt Priority Tier |
|---|---|---|
| 0 | 0 | Priority 0 (Lowest Tier) |
| 0 | 1 | Priority 1 (Low Tier) |
| 1 | 0 | Priority 2 (High Tier) |
| 1 | 1 | Priority 3 (Highest Interrupt Tier) |
Upon detection of a pending interrupt request, the microcontroller hardware executes the following fixed sequence of operations automatically:
| Interrupt Source Flag | Interrupt Jump Vector Address (Hexadecimal) |
|---|---|
| IE0 (INT0 External Interrupt) | 03h |
| TF0 (Timer T0 Overflow) | 0Bh |
| IE1 (INT1 External Interrupt) | 13h |
| TF1 (Timer T1 Overflow) | 1Bh |
| RI, TI, SPIF (UART/SPI Serial Interrupt) | 23h |
| TF2, EXF2 (Timer T2 Overflow/Capture) | 2Bh |
| All listed vector addresses are formatted in hexadecimal notation | |
Dedicated interrupt service subroutines are stored at each vector address offset. In practical firmware implementations, these vector locations typically contain unconditional jump instructions pointing to the full interrupt handler code located elsewhere in program memory.
4. Once the interrupt service subroutine finishes executing, the hardware pops the previously stored return address from the stack back into the program counter register, and main-line application code resumes execution at the exact point it was interrupted.
The AT89S8253 integrates three independent timer/counter peripherals designated T0, T1, and T2. Timers T0 and T1 fully comply with the original standard 8051 peripheral specification, with no functional deviations from the classic architecture implementation.
Timer 2 is a 16-bit timer/event counter peripheral exclusive to enhanced generations of the 8051 microcontroller family, differing structurally from T0 and T1 with four dedicated control registers. Two registers, TH2 and TL2, concatenate to form the primary 16-bit counting register pair. Identical to T0 and T1, Timer 2 can operate in either internal clock timer mode or external pulse event counter mode. The remaining two registers, RCAP2H and RCAP2L, also form a concatenated 16-bit storage pair acting as hardware capture/autoreload holding registers to snapshot counter values temporarily.
The primary advantage of Timer 2 relative to T0 and T1 is simplified single-instruction handling of all read and value swap operations. Like T0 and T1, Timer 2 supports four distinct configurable operating modes detailed later within this chapter.
This control register contains bit fields governing all operating modes and trigger conditions for the Timer 2 peripheral.
TF2 Hardware automatically asserts the TF2 overflow flag when the 16-bit TH2+TL2 counter reaches maximum value and rolls over to zero. Firmware software must manually clear this flag to detect subsequent overflow events. If either the RCLK or TCLK baud rate generator bits are set, counter overflow events do not modify the TF2 flag state.
EXF2 The EXF2 flag hardware-sets whenever a falling edge signal on the T2EX hardware pin triggers a capture or automatic reload operation. This flag generates an interrupt request (if interrupt masking is disabled), with one exception: when the DCEN bit inside T2MOD is asserted, EXF2 loses its interrupt trigger functionality. Application code must manually clear the EXF2 flag after handling related events.
RCLK Receive clock selection bit defining the timer source for UART serial port receive baud rate generation:
TCLK Transmit clock selection bit defining the timer source for UART serial port transmit baud rate generation:
EXEN2 Timer 2 external trigger enable bit, which integrates the T2EX hardware pin into Timer 2 peripheral logic:
TR2 Timer 2 run enable bit to activate or halt counter increment/decrement operation:
C/T2 Timer or event counter mode selection bit to choose the pulse source incrementing the T2 counter register pair:
CP/RL2 Capture versus automatic reload mode selector bit defining the data transfer direction between counter and RCAP2 holding registers:
Timers serve legitimate use cases generating synchronous timing clocks for serial communication interfaces, yet they also create exploitable security attack surfaces. Attackers can leverage precise timer measurement capabilities to record execution latency differences within cryptographic algorithm subroutines, executing timing side-channel attacks to extract secret encryption keys. Secure cryptography implementation best practices mandate constant-time execution logic that avoids variable-length timer operations within security-critical code segments to mitigate these leakage vulnerabilities.
When the CP/RL2 bit inside T2CON is asserted to logic one, Timer 2 enters the dedicated capture operating mode as illustrated in the referenced diagram. In capture mode, the live counter value held within TH2 and TL2 can be instantly copied into the RCAP2H/RCAP2L holding register pair without interrupting continuous counter incrementing. The full capture mode operational sequence operates as follows:
Capture Mode Configuration Bit Settings:
Auto-reload mode configures Timer T2 as a bidirectional 16-bit timer or external event counter with hardware-managed automatic value reloading upon overflow. Count direction control is governed by the DCEN bit within the T2MOD auxiliary timer mode register. Asserting DCEN enables bidirectional counting (upward or downward), with the T2EX hardware pin selecting the active direction mode:
T2OE Enables Timer T2 to generate a continuous independent square-wave clock signal output on its dedicated I/O pin.
DCEN When asserted to logic one, enables bidirectional counting operation (both upward increment and downward decrement).
As visualized in the diagram above, auto-reload mode reverses the data transfer direction compared to capture mode: upon counter overflow, the pre-stored values within RCAP2H and RCAP2L are automatically copied into the primary TH2/TL2 counter register pair to reset the counting starting value.
Auto Reload Mode Configuration Bit Settings are summarized in the following diagram:
All previously described unidirectional auto-reload behavior applies exclusively when the DCEN bit inside T2MOD remains cleared to logic zero. If DCEN is asserted, Timer T2 switches to bidirectional counting, with the T2EX pin state determining the active direction:
T2EX = 0 → Timer T2 counts downward (decrement mode)
T2EX = 1 → Timer T2 counts upward (increment mode)
During upward counting with DCEN=1, the overall functional sequence matches standard unidirectional auto-reload mode with a single modification to the EXF2 flag’s operational behavior.
During downward counting with DCEN=1, an overflow condition triggers when the TH2/TL2 counter value matches the RCAP2H/RCAP2L reload value. This match event asserts the TF2 overflow flag and sets all bits within TH2 and TL2 to logic one, while the counter continues decrementing sequentially through values 65535, 65534, 65533, and so on.
Under both upward and downward bidirectional counting scenarios, the EXF2 flag takes on a modified hardware function. Upon overflow detection, this bit toggles its signal state and loses its original interrupt generation capability. Instead, EXF2 acts as an extra 17th carry bit for the counting register pair, effectively extending Timer T2 into a virtual 17-bit counter peripheral.
Timer T2 can simultaneously operate as both a UART baud rate clock source and independent square-wave clock generator. If either the RCLK or TCLK bit within T2CON is asserted, Timer T2 reconfigures into a dedicated baud rate generator peripheral, operating with nearly identical internal logic to standard auto-reload mode. The baud rate calculation formula is displayed in the referenced graphic below:
Critical operational specifications for baud rate generator mode:
As previously noted, Timer T2 supports standalone square-wave clock generation functionality. In all prior operating modes, the P1.0 hardware pin (labeled T2 in block diagrams) functions as an external pulse input for counter event counting. This pin can alternatively be configured as a continuous clock signal output driver. When paired with a 16 MHz crystal oscillator, the generated output square wave frequency ranges from 61 Hz up to 4 MHz with a fixed 50% duty cycle.
hardware security research is to improve the overall securityTo enable clock output mode on the T2/P1.0 pin, the C/T2 bit inside T2CON must be cleared to zero, while the T2OE bit within the T2MOD register must be asserted to logic one. Asserting the TR2 run bit activates the timer counter, and the P1.0 pin begins outputting a continuous rectangular wave whose frequency can be calculated via the formula shown in the referenced graphic:
The integrated UART peripheral maintains full functional parity with the standard UART implementation found on baseline 8051 microcontrollers. It supports four distinct asynchronous communication operating modes, selected via the SM0 and SM1 bit fields within the SCON serial control register.
The UART serial communication interface creates a significant reverse engineering attack vector if the device memory lock protection is left unconfigured. Attackers can passively monitor the TXD transmit pin to capture unencrypted plaintext data transmitted during normal runtime operation. If the product implements UART-based bootloader firmware upload functionality without active lockbit security, adversaries can directly extract complete firmware binaries via serial port read commands. Proper lockbit configuration is mandatory to block these unauthorized memory read operations.
Multiprocessor serial communication mode activates when the SM2 bit inside SCON is asserted, enabling automatic hardware address filtering for multi-drop serial bus topologies. The serial port hardware independently evaluates the address identifier embedded within every incoming serial frame, eliminating the requirement for all connected microcontrollers to execute address comparison logic in application firmware and drastically simplifying multi-device network software development. The complete operational workflow is detailed below for clarity.
Two dedicated special function registers, SADDR and SADEN, deliver flexible multiprocessor addressing functionality. Each slave device stores its unique hardware identifier address within the SADDR register, while the SADEN register holds a programmable address mask value. Mask bits configured as don’t-care wildcards allow the master controller to target either individual slave nodes or broadcast data to multiple slave devices simultaneously. In short, the SADEN mask register defines which bit positions within the SADDR slave address register are evaluated during address matching and which bits are ignored by hardware filtering logic.
When the master controller intends to transmit data to a specific slave device on the serial bus, it first transmits a dedicated address frame byte to identify the target node. Address bytes are distinguished from standard data bytes by a logic one value on the ninth frame bit, while data frames carry a logic zero ninth bit. After receiving an address frame, every connected slave executes a hardware address match check against its SADDR/SADEN configuration. The matching target slave automatically clears its SM2 flag to enable reception of subsequent data frames. All non-matching slave nodes retain their SM2 flag set to logic one and ignore all incoming data frames until a new address byte is transmitted by the master.
A simplified example of a three-node microcontroller mini-network demonstrates this addressing scheme:
Microcontroller A operates as the master node, communicating with slave devices labeled B and C.
Microcontroller B: SADDR = 1100 0000
SADEN = 1111 1101
Match Address Mask = 1100 00X0
Microcontroller C: SADDR = 1100 0000
SADEN = 1111 1110
Match Address Mask = 1100 000X
Although both slave B and slave C share an identical base address value of 1100 0000, unique wildcard masks stored inside their respective SADEN registers enable individual or broadcast addressing from the master controller:
Transmitting address byte 1100 0010 routes data exclusively to slave device B.
Transmitting address byte 1100 0001 routes data exclusively to slave device C.
Transmitting address byte 1100 0000 triggers a broadcast transmission received by both slave devices simultaneously.
In addition to the asynchronous UART serial peripheral, the AT89S8253 integrates a high-speed synchronous SPI communication module, an extension not included within the original baseline 8051 peripheral specification. The SPI interface enables full-duplex synchronous data transfers between the host microcontroller and one or more external slave peripherals, or between multiple interconnected microcontroller devices. One device on the SPI bus assumes the master role exclusively; the master defines the serial clock frequency, data transmission direction (transmit or receive), and serial bit frame format. All remaining bus devices operate as subordinate slave nodes, which cannot initiate data transfer operations and must synchronize fully to timing and formatting parameters set by the active master controller.
SPI data transfers utilize a full-duplex differential bus composed of three dedicated signal lines mapped to hardware pins MISO (P1.6), MOSI (P1.5), and SCK (P1.7). The fourth SPI control signal, the SS slave select pin, is unused on master-mode devices and can be repurposed as a general-purpose digital input/output pin. For slave-mode operation, the SS pin must be held at a logic low voltage level to activate the SPI peripheral; asserting the SS pin high disables the slave SPI module and releases the MOSI pin for general I/O functionality.
As illustrated in the schematic diagram, the input/output direction of the MISO and MOSI pins reverses between master and slave operating modes, controlled entirely by the MSTR bit field inside the SPCR SPI control register.
Understanding SPI signal pin abbreviations simplifies hardware wiring implementation:
MISO = Master Input, Slave Output; MOSI = Master Output, Slave Input; SCK = Serial Clock; SS = Slave Select Chip Enable;
Identical to most on-chip peripherals within the microcontroller, the SPI module supports multiple configurable operating modes via dedicated control register bits.
The SPI bus acts as the primary hardware programming interface for the AT89S8253. If device lockbit security protections remain unprogrammed, attackers only need to physically connect test probes to the four SPI signal pins to perform full flash memory read-back and complete firmware extraction. Even with lockbit protections activated, specialized hardware fault injection attacks can inject precise clock glitches into the SCK line to force the microcontroller to output protected memory data during programming mode entry. For maximum device security, manufacturers must program the highest lockbit security tier, which permanently disables all SPI memory read-back command functionality.
Data bytes written to the SPI data register SPDR are automatically transferred into an internal 8-bit hardware shift register. The SPI clock generator activates, and serial bit data streams out sequentially on the MOSI transmit pin. A brief synchronization delay may occur during initial bus startup to align internal logic timing with the main MCU oscillator.
Upon completion of single-byte transmission, the SPI clock generator halts automatically, the SPIF transfer complete interrupt flag bit is asserted, the received incoming byte from the slave device is latched into the SPDR register, and an SPI interrupt request generates if the SPIE global SPI interrupt enable bit and ES serial interrupt enable bit are both asserted.
Attempting to write a new byte value to the SPDR register mid-way through an active transmission cycle triggers the WCOL write collision error flag bit. This flag signals invalid premature write operations. The original byte in transmission will complete successfully, while the newly written byte value is discarded with no transmission occurring.
Enhanced buffered SPI mode shares core functional logic with standard normal mode, with the critical addition of an intermediate hardware buffer register between the SPDR data register and the main shift register. While this extra storage stage appears redundant at first glance, it delivers significant throughput improvements for bulk multi-byte data transfers, as visualized in the referenced diagram below.
Data written to the SPDR register automatically transfers into the intermediate capture buffer register, which immediately asserts the WCOL flag bit to indicate the buffer storage stage holds pending data. Further write operations to SPDR while the buffer remains full will trigger overflow collision conditions. Hardware logic automatically clears the WCOL flag once buffered data transfers from the intermediate buffer into the main shift register and serial transmission commences. If the byte written to SPDR is the first frame of a transfer sequence, the data immediately moves into the empty shift register, clearing the WCOL flag to signal an empty buffer state.
While one byte transmission is underway, the subsequent byte to be sent can be written into the SPDR register. This new byte will be immediately transferred to the internal transmit buffer. To determine whether a data transmission operation is active, users only need to check the logic level of the LDEN bit within the SPSR register. If this bit is asserted (Load Enable) and the WCOL bit remains cleared, a transmission is currently running and the transmit buffer is empty, which allows writing the next byte into the SPDR register without conflict.
How to select the optimal SPI operating mode? If only sporadic single-byte transmissions are required, there is no need for complex configuration—the standard normal mode serves as the most straightforward solution. When bulk data transfer is necessary, the enhanced mode delivers superior performance: the internal clock oscillator stays enabled as long as the transmit buffer is periodically refilled and the WCOL flag is triggered. Furthermore, this mode eliminates synchronization overhead and facilitates high-efficiency, seamless data streaming.
The SPI peripheral is managed by three dedicated special function registers: SPDR, SPSR, and SPCR.
The SPDR register stores outgoing serial data for SPI transmission and also captures all incoming received serial data.
SPIF SPI Interrupt Flag. This bit is automatically set upon completion of a full byte data transfer. If the SPIE and ES interrupt enable bits are both set, an SPI interrupt request will be generated. The SPIF flag is cleared by consecutively reading the SPSR register followed by either a read or write access to the SPDR register.
WCOL Write Collision Flag. In normal operating mode (ENH=0), this bit latches high if the firmware attempts to write SPDR mid-transmission; such premature write operations are discarded with no impact on ongoing transfers, defined as a Write Collision event. The flag is cleared using the identical sequence required to clear the SPIF bit.
In enhanced mode (ENH=1), WCOL is asserted when the transmit buffer holds valid pending data, signaling that new data is ready to be shifted into the main shift register for transmission.
In enhanced mode, new transmit data may be loaded into the transmit buffer only after the WCOL flag has been cleared.
DISSO Slave Output Disable Bit. When set, this bit tri-states the MISO hardware pin, enabling multiple slave microcontrollers to share a single SPI bus interface. Conventionally, all connected slave devices receive the initial address byte, and only the target slave shall clear its own DISSO bit to drive the MISO line for subsequent data exchange.
ENH
0 Configures the SPI peripheral for normal operation mode without hardware transmit buffering.
1 Enables the SPI enhanced buffered operating mode.
SPIE SPI Interrupt Enable. Asserting this bit permits the SPI module to generate hardware interrupt requests upon transfer completion.
SPE SPI Peripheral Enable. This bit activates SPI communication functionality. Once set, the SS, MOSI, MISO, and SCK hardware pins are multiplexed to microcontroller port pins P1.4, P1.5, P1.6, and P1.7 respectively.
DORD Data Order Bit. Defines the bit transmission sequence for serial SPI frames:
MSTR Master/Slave Mode Select. Determines whether the microcontroller acts as an SPI master or slave device on the bus:
CPOL Clock Polarity Bit. Sets the idle logic state of the SCK clock pin when no SPI transfer is active:
CPHA Clock Phase Bit. Combined with the CPOL setting, this bit controls the relative timing relationship between serial clock edges and data sampling. Refer to the timing diagrams provided below for reference.
SPR1,SPR0 SPI Clock Rate Select Bits. When the SPI module is configured as master, these two bits set the master serial clock (SCK) baud rate frequency. In slave operation mode, these bits have no functional effect; the SPI bus clock speed is fully dictated by the external master controller.
| SPR1 | SPR0 | SCK Clock Frequency |
|---|---|---|
| 0 | 0 | Fosc/4 |
| 0 | 1 | Fosc/16 |
| 1 | 0 | Fosc/64 |
| 1 | 1 | Fosc/128 |
Serial frame timing diagram for CPHA=0 configuration
* Signal state undefined; typically holds the MSB value of the previously received data byte.
Serial frame timing diagram for CPHA=1 configuration
* Signal state undefined; typically holds the LSB value of the previously received data byte.
Two critical rules must be followed during SPI peripheral initialization:
Identical to all other 8051 architecture microcontrollers, this device supports three distinct power operating modes: Normal Mode (typical current draw ~25 mA), Idle Mode (typical current draw ~6.5 mA), and Power-Down Mode (typical current draw ~40 μA). Operating mode selection is controlled via dedicated flag bits inside the PCON Power Control Register. Three register bits feature modified functionality compared to baseline standard 8051 variants:
PCON register overview
Functional description for each bit within the PCON register:
SMOD1 Double UART Baud Rate Enable. When asserted, this bit doubles the base serial communication baud rate frequency.
SMOD0 SCON Register Bit 7 Function Select. This bit redefines the operational purpose of the highest bit inside the SCON serial control register:
POF Power-On Reset Flag. Automatically set after power supply voltage rises above the 3V threshold during initial device power-up. This flag enables firmware to differentiate between cold power-on resets and wake-up resets triggered after exiting Power-Down low-power mode.
GF1 General-Purpose User Flag Bit, available for arbitrary firmware storage and status tracking.
GF0 General-Purpose User Flag Bit, available for arbitrary firmware storage and status tracking.
PD Power-Down Mode Trigger. Writing logic 1 to this bit forces the microcontroller into full Power-Down low-power operating state.
IDL Idle Mode Trigger. Writing logic 1 to this bit places the microcontroller into low-power Idle operating state.
The Power-Down mode can be leveraged as a hardware security countermeasure: if physical tampering events are detected by peripheral logic, the MCU may immediately enter Power-Down state to halt all internal clock oscillators, significantly complicating memory readout attacks by malicious actors. However, with stable power supply maintained, attackers may still perform chip decapsulation to directly probe internal memory cells. The Idle power mode carries inherent vulnerability to clock glitching attacks, as the main oscillator remains active while the CPU core execution pipeline is suspended; this condition creates opportunities for side-channel analysis to extract sensitive bus data.
When unexpected abnormal behavior occurs during microcontroller runtime operation, root cause analysis almost never points to intrinsic hardware defects of the MCU itself. Although non-obvious at first glance, the microcontroller strictly executes every machine instruction stored in program memory without deviation. For this reason, developers must exercise extreme caution around several high-risk critical points during source code development, starting with RAM memory layout management.
While the integrated RAM space is dimensioned to satisfy most embedded application requirements and incorporates all required memory regions, the entire RAM pool exists as a single contiguous physical memory block. No hardware isolation separates register banks R0–R7, general-purpose scratchpad memory, and stack storage regions—these functional partitions are merely logical address ranges mapped onto the unified RAM address space. Refer to the accompanying memory map diagram for clarification.
Failure to account for this unified memory architecture introduces severe risk of unpredictable, erratic program execution. The following design precautions mitigate such memory corruption faults:
If firmware exclusively utilizes Register Bank 0’s R0–R7 registers, memory addresses 08h through 1Fh remain safely available for general variable storage. When alternate register banks (1, 2, or 3) are activated, developers must avoid writing to memory addresses below 20h, as such accesses risk overwriting active bank R register contents and corrupting runtime state.
If the application source code does not implement bit-addressable boolean variables, the memory address range 20h–2Fh may be freely allocated for data storage. Firmware employing bit variables must exercise strict care when modifying addresses in this range to prevent accidental corruption of stored bit flags.
By default, the stack pointer initializes stack storage starting at memory address 08h. Activation of Register Banks 1, 2, or 3 will overwrite their register values with stack push operations. Industry best practice dictates reinitializing the Stack Pointer register to an address greater than 20h (or higher) at the very beginning of the main program execution flow.
Special Function Registers (SFRs) provide dedicated hardware peripheral control interfaces, each assigned a unique predefined function. SFR addresses cannot be repurposed as general-purpose scratchpad memory, even if unused bit positions exist within individual register bytes.
The microcontroller’s native instruction set supports direct bit manipulation operations targeting all byte addresses from 20h to 7Fh in internal RAM. Additionally, a subset of Special Function Registers supports direct single-bit access; only SFRs assigned base addresses evenly divisible by eight qualify for bitwise addressing capability.
When external RAM or program ROM memory expansion hardware is connected, Port 0 and Port 2 become permanently dedicated address/data bus lines and cannot be repurposed for general digital I/O, regardless of how few physical pins are electrically connected to the external memory chips.
The DPTR data pointer is a composite 16-bit register split into two independent 8-bit segments: DPH (high byte) and DPL (low byte). All stack and memory operations must treat DPTR as this two-part structure. As an example, when pushing the full DPTR value onto the system stack, the DPL low byte must be pushed first, followed by the DPH high byte.
UART serial communication peripherals are fully configured via the SCON serial control register. Supplementary setup of the TCON and TMOD timer configuration registers is also mandatory, as Timer 1 serves as the primary baud rate clock generator for standard UART operation.
Enabling hardware interrupt functionality introduces substantial risk of non-deterministic program crashes if proper context preservation protocols are omitted. Upon receiving an interrupt request signal, the microcontroller completes execution of the currently active machine instruction, pushes the return program counter address onto the stack to resume main code later, then jumps execution to the assigned interrupt service routine vector address. Once the interrupt routine finishes, the MCU pops the stored return address from the stack and resumes primary application code execution. However, a critical oversight frequently introduces catastrophic runtime faults:
The hardware stack only preserves the program counter return address for post-interrupt resumption. Numerous core registers will have their values modified during interrupt service routine execution. If original register states are not saved and restored before exiting the interrupt handler, the main application logic will operate using corrupted register data, triggering full program instability. This fault condition may manifest immediately upon interrupt triggering or remain latent for days depending on interrupt event timing. The definitive resolution requires saving all critical register context at the start of each interrupt service routine and restoring original register values prior to executing the interrupt return instruction. Registers requiring mandatory context backup include:
Important Note: Register context preservation is conventionally implemented with PUSH stack instructions. Direct mnemonics such as PUSH R0 cannot be utilized for banked register storage. The microcontroller hardware cannot resolve which physical register bank corresponds to the generic R0–R7 label, as four independent banks share identical register naming. Instead, developers must push the absolute RAM base address of each target register (for example, PUSH 00h to save Bank 0 R0) onto the stack.
When executing indirect addressing instructions via R0/R1 pointers, avoid using these operations to access Special Function Registers. The microcontroller hardware ignores SFR memory mapping during indirect access and instead targets internal RAM locations sharing identical byte addresses with SFRs, causing unintended data writes to scratchpad memory.
The UART serial transmit complete flag (TI) and receive complete flag (RI) within the SCON register generate a shared single interrupt vector. When this combined UART interrupt fires, firmware must poll both flag bits to identify the interrupt source: transmit completion, receive completion, or simultaneous transmit/receive events. Developers must manually clear TI and RI flags via software logic after handling the corresponding interrupt event; leaving either flag asserted creates an infinite interrupt loop where the same service routine executes continuously without exit.
These widespread firmware coding mistakes carry tangible embedded security vulnerabilities. For instance, stack corruption inside an interrupt handler can trigger uncontrolled program counter jumps to arbitrary memory addresses, creating exploitable attack surfaces for injection of malicious executable code. In secure locked embedded systems, such memory corruption bugs may inadvertently disable anti-tamper lock protection mechanisms if interrupt vector table addresses become overwritten. Rigorous defensive coding practices are therefore essential to eliminate exploitable weaknesses that simplify reverse engineering and hardware hacking efforts.
Accumulator Register (Base Address: E0h)
| ACC | ||||||||
|---|---|---|---|---|---|---|---|---|
| Post-Reset Value | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| Bit Designator | - | - | - | - | - | - | - | - |
| Absolute Bit Address | E7 | E6 | E5 | E4 | E3 | E2 | E1 | E0 |
S29Cxx Series hack controller firmware protection: S29C31001B S29C31001T S29C31002B S29C31002T S29C31004B S29C31004T S29C51001B S29C51001T S29C51002B S29C51002T S29C51004B S29C51004T ...
MSUxx Series read out microcontroller protection: MSU1958 MSU2952 MSU2964 MSU2958 ...
SM29xx Series hack controller lockbit protection: SM2951 SM2952 SM2954 SM2958 SM2964 SM2965 ...
SM59xx Series read out microcontroller lockbit protection: SM59064 SM59128C SM59128L SM5912C SM5912L SM5916C SM59164 SM5916L SM59264 SM5964 SM5964A SM5964AC SM5964AL SM5964C SM5964D0 SM5964D0A SM5964D1A SM59D02G2C SM59D02G2L SM59D03G2C SM59D03G2L SM59D04G2C SM59D04G2L SM59R08A2 ...
SM59xx Series hack microcontroller protection: SM7908 SM79108 SM79164 SM79164L SM79164V SM7932 SM7964 ...
SM59xx Series hack controller lockbit protection: SM894051 SM8951 SM89516 SM89516A SM89516AL SM89516B SM89516BL SM89516L SM8951A SM8951AL SM8951B SM8951BL SM8951L SM8952 SM8952A SM8952AL SM8952B SM8952BL SM8952L SM8954 SM8954A SM8954AL SM8954B SM8954BL SM8954L SM8958 SM8958A SM8958AL SM8958B SM8958BL SM8958L SM89S16R1C SM89T04R1C SM89T04R1L SM89T08R1C SM89T08R1L SM89T16R1C SM89T16R1L ..
Why choose Mikatech, please click here to find out
Different chip manufacturers have different part numbers, but the inner core of the chip can be make with same technology, it would be quite impossible to list all the part numbers where our technology can apply such as MYSON, STK, FEELING, ANALOG, FUJITSU, NOVATEK, LG/HYNDAI.
Also by the advancing of the technology, everyday we gain more and more experience and develope new methods for reverse engineering for different Intergated Circuit parts. Full list of Integrated Circuit part numbers which is within our scope of capability is always getting bigger, please contact us to find out.
Mikatech Innovative Limited understands the importance of its clients' privacy. At the moment you contact Mikatech, the personal information from you will be put under protection by our management regulations which was developed by our years of practice, Mikatech uses these information to customize its service to you, it will never disclose these information to third party out of any reason.
Every project we did, we will delete all the data, materials, and codes 60days after deliverig the files, it iwll protect us and protect your privacy.
Yes, it is totally legal.
Mikatech deliver its reverse engineering services for educational purposes only, it can be illegal to use above mentioned services in some coutries or regions, please check your local laws.
Mikatech does not take any responsibility in relation to the use of above mentioned services that may be considered illegal.