8051

8051 Instruction Set

Instructions by Opcode

0x_00x_10x_20x_30x_40x_50x_60x_70x_80x_90x_a0x_b0x_c0x_d0x_e0x_f
0x00NOPAJMPLJMPRRINCINCINCINCINCINCINCINCINCINCINCINC
0x10JBCACALLLCALLRRCDECDECDECDECDECDECDECDECDECDECDECDEC
0x20JBAJMPRETRLADDADDADDADDADDADDADDADDADDADDADDADD
0x30JNBACALLRETIRLCADDCADDCADDCADDCADDCADDCADDCADDCADDCADDCADDCADDC
0x40JCAJMPORLORLORLORLORLORLORLORLORLORLORLORLORLORL
0x50JNCACALLANLANLANLANLANLANLANLANLANLANLANLANLANLANL
0x60JZAJMPXRLXRLXRLXRLXRLXRLXRLXRLXRLXRLXRLXRLXRLXRL
0x70JNZACALLORLJMPMOVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOV
0x80SJMPAJMPANLMOVCDIVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOV
0x90MOVACALLMOVMOVCSUBBSUBBSUBBSUBBSUBBSUBBSUBBSUBBSUBBSUBBSUBBSUBB
0xa0ORLAJMPMOVINCMUL?MOVMOVMOVMOVMOVMOVMOVMOVMOVMOV
0xb0ANLACALLCPLCPLCJNECJNECJNECJNECJNECJNECJNECJNECJNECJNECJNECJNE
0xc0PUSHAJMPCLRCLRSWAPXCHXCHXCHXCHXCHXCHXCHXCHXCHXCHXCH
0xd0POPACALLSETBSETBDADJNZXCHDXCHDDJNZDJNZDJNZDJNZDJNZDJNZDJNZDJNZ
0xe0MOVXAJMPMOVXMOVXCLRMOVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOV
0xf0MOVXACALLMOVXMOVXCPLMOVMOVMOVMOVMOVMOVMOVMOVMOVMOVMOV

Row = high nibble, column = low nibble (e.g. row 0x20 / col 0x04 = opcode 0x24, ADD A,#data). Click any cell to jump to that instruction's full entry.

ACALL Absolute Call Within 2K Block

▸
ACALL code address
InstructionOpCodeBytesFlags
ACALL page00x112None
ACALL page10x312None
ACALL page20x512None
ACALL page30x712None
ACALL page40x912None
ACALL page50xB12None
ACALL page60xD12None
ACALL page70xF12None

ACALL unconditionally calls a subroutine at the indicated code address. ACALL pushes the address of the instruction that follows ACALL onto the stack, least-significant-byte first, most-significant-byte second. The Program Counter is then updated so that program execution continues at the indicated address.

The new value for the Program Counter is calculated by replacing the least-significant-byte of the Program Counter with the second byte of the ACALL instruction, and replacing bits 0-2 of the most-significant-byte of the Program Counter with 3 bits that indicate the page. Bits 3-7 of the most-significant-byte of the Program Counter remain unchaged.

Since only 11 bits of the Program Counter are affected by ACALL, calls may only be made to routines located within the same 2k block as the first byte that follows ACALL.

See Also: LCALL RET

ADD, ADDC Add Accumulator, Add Accumulator With Carry

▸
ADD A,operand ADDC A,operand
InstructionOpCodeBytesFlags
ADD A,#data0x242CACOV
ADD A,iram addr0x252CACOV
ADD A,@R00x261CACOV
ADD A,@R10x271CACOV
ADD A,R00x281CACOV
ADD A,R10x291CACOV
ADD A,R20x2A1CACOV
ADD A,R30x2B1CACOV
ADD A,R40x2C1CACOV
ADD A,R50x2D1CACOV
ADD A,R60x2E1CACOV
ADD A,R70x2F1CACOV
ADDC A,#data0x342CACOV
ADDC A,iram addr0x352CACOV
ADDC A,@R00x361CACOV
ADDC A,@R10x371CACOV
ADDC A,R00x381CACOV
ADDC A,R10x391CACOV
ADDC A,R20x3A1CACOV
ADDC A,R30x3B1CACOV
ADDC A,R40x3C1CACOV
ADDC A,R50x3D1CACOV
ADDC A,R60x3E1CACOV
ADDC A,R70x3F1CACOV

ADD and ADDC both add the value operand to the value of the Accumulator, leaving the resulting value in the Accumulator. The value operand is not affected. ADD and ADDC function identically except that ADDC adds the value of operand as well as the value of the Carry flag whereas ADD does not add the Carry flag to the result.

The Carry bit (C) is set if there is a carry-out of bit 7. In other words, if the unsigned summed value of the Accumulator, operand and (in the case of ADDC) the Carry flag exceeds 255 Carry is set. Otherwise, the Carry bit is cleared.

The Auxillary Carry (AC) bit is set if there is a carry-out of bit 3. In other words, if the unsigned summed value of the low nibble of the Accumulator, operand and (in the case of ADDC) the Carry flag exceeds 15 the Auxillary Carry flag is set. Otherwise, the Auxillary Carry flag is cleared.

The Overflow (OV) bit is set if there is a carry-out of bit 6 or out of bit 7, but not both. In other words, if the addition of the Accumulator, operand and (in the case of ADDC) the Carry flag treated as signed values results in a value that is out of the range of a signed byte (-128 through +127) the Overflow flag is set. Otherwise, the Overflow flag is cleared.

See Also: SUBB DA INC DEC

AJMP Absolute Jump Within 2K Block

▸
AJMP code address
InstructionOpCodeBytesFlags
AJMP page00x012None
AJMP page10x212None
AJMP page20x412None
AJMP page30x612None
AJMP page40x812None
AJMP page50xA12None
AJMP page60xC12None
AJMP page70xE12None

AJMP unconditionally jumps to the indicated code address. The new value for the Program Counter is calculated by replacing the least-significant-byte of the Program Counter with the second byte of the AJMP instruction, and replacing bits 0-2 of the most-significant-byte of the Program Counter with 3 bits that indicate the page of the byte following the AJMP instruction. Bits 3-7 of the most-significant-byte of the Program Counter remain unchaged.

Since only 11 bits of the Program Counter are affected by AJMP, jumps may only be made to code located within the same 2k block as the first byte that follows AJMP.

See Also: LJMP SJMP

ANL Bitwise AND

▸
ANL operand1, operand2
InstructionOpCodeBytesFlags
ANL iram addr,A0x522None
ANL iram addr,#data0x533None
ANL A,#data0x542None
ANL A,iram addr0x552None
ANL A,@R00x561None
ANL A,@R10x571None
ANL A,R00x581None
ANL A,R10x591None
ANL A,R20x5A1None
ANL A,R30x5B1None
ANL A,R40x5C1None
ANL A,R50x5D1None
ANL A,R60x5E1None
ANL A,R70x5F1None
ANL C,bit addr0x822C
ANL C,/bit addr0xB02C

ANL does a bitwise "AND" operation between operand1 and operand2, leaving the resulting value in operand1. The value of operand2 is not affected. A logical "AND" compares the bits of each operand and sets the corresponding bit in the resulting byte only if the bit was set in both of the original operands, otherwise the resulting bit is cleared.

See Also: ORL XRL

CJNE Compare and Jump If Not Equal

▸
CJNE operand1,operand2,reladdr
InstructionOpCodeBytesFlags
CJNE A,#data,reladdr0xB43C
CJNE A,iram addr,reladdr0xB53C
CJNE @R0,#data,reladdr0xB63C
CJNE @R1,#data,reladdr0xB73C
CJNE R0,#data,reladdr0xB83C
CJNE R1,#data,reladdr0xB93C
CJNE R2,#data,reladdr0xBA3C
CJNE R3,#data,reladdr0xBB3C
CJNE R4,#data,reladdr0xBC3C
CJNE R5,#data,reladdr0xBD3C
CJNE R6,#data,reladdr0xBE3C
CJNE R7,#data,reladdr0xBF3C

CJNE compares the value of operand1 and operand2 and branches to the indicated relative address if operand1 and operand2 are not equal. If the two operands are equal program flow continues with the instruction following the CJNE instruction.

The Carry bit (C) is set if operand1 is less than operand2, otherwise it is cleared.

See Also: DJNZ

CLR Clear Register

▸
CLR register
InstructionOpCodeBytesFlags
CLR bit addr0xC22None
CLR C0xC31C
CLR A0xE41None

CLR clears (sets to 0) all the bit(s) of the indicated register. If the register is a bit (including the carry bit), only the specified bit is affected. Clearing the Accumulator sets the Accumulator's value to 0.

See Also: SETB

CPL Complement Register

▸
CPL operand
InstructionOpCodeBytesFlags
CPL A0xF41None
CPL C0xB31C
CPL bit addr0xB22None

CPL complements operand, leaving the result in operand. If operand is a single bit then the state of the bit will be reversed. If operand is the Accumulator then all the bits in the Accumulator will be reversed. This can be thought of as "Accumulator Logical Exclusive OR 255" or as "255-Accumulator." If the operand refers to a bit of an output Port, the value that will be complemented is based on the last value written to that bit, not the last value read from it.

See Also: CLR SETB

DA Decimal Adjust Accumulator

▸
DA A
InstructionOpCodeBytesFlags
DA0xD41C

DA adjusts the contents of the Accumulator to correspond to a BCD (Binary Coded Decimal) number after two BCD numbers have been added by the ADD or ADDC instruction. If the carry bit is set or if the value of bits 0-3 exceed 9, 0x06 is added to the accumulator. If the carry bit was set when the instruction began, or if 0x06 was added to the accumulator in the first step, 0x60 is added to the accumulator.

The Carry bit (C) is set if the resulting value is greater than 0x99, otherwise it is cleared.

See Also: ADD, ADDC

DEC Decrement Register

▸
DEC register
InstructionOpCodeBytesFlags
DEC A0x141None
DEC iram addr0x152None
DEC @R00x161None
DEC @R10x171None
DEC R00x181None
DEC R10x191None
DEC R20x1A1None
DEC R30x1B1None
DEC R40x1C1None
DEC R50x1D1None
DEC R60x1E1None
DEC R70x1F1None

DEC decrements the value of register by 1. If the initial value of register is 0, decrementing the value will cause it to reset to 255 (0xFF Hex). Note: The Carry Flag is NOT set when the value "rolls over" from 0 to 255.

See Also: INC SUBB

DIV Divide Accumulator by B

▸
DIV AB
InstructionOpCodeBytesFlags
DIV AB0x841COV

Divides the unsigned value of the Accumulator by the unsigned value of the "B" register. The resulting quotient is placed in the Accumulator and the remainder is placed in the "B" register.

The Carry flag (C) is always cleared.

The Overflow flag (OV) is set if division by 0 was attempted, otherwise it is cleared.

See Also: MUL AB

DJNZ Decrement and Jump if Not Zero

▸
DJNZ register,reladdr
InstructionOpCodeBytesFlags
DJNZ iram addr,reladdr0xD53None
DJNZ R0,reladdr0xD82None
DJNZ R1,reladdr0xD92None
DJNZ R2,reladdr0xDA2None
DJNZ R3,reladdr0xDB2None
DJNZ R4,reladdr0xDC2None
DJNZ R5,reladdr0xDD2None
DJNZ R6,reladdr0xDE2None
DJNZ R7,reladdr0xDF2None

DJNZ decrements the value of register by 1. If the initial value of register is 0, decrementing the value will cause it to reset to 255 (0xFF Hex). If the new value of register is not 0 the program will branch to the address indicated by relative addr. If the new value of register is 0 program flow continues with the instruction following the DJNZ instruction.

See Also: DEC JZ JNZ

INC Increment Register

▸
INC register
InstructionOpCodeBytesFlags
INC A0x041None
INC iram addr0x052None
INC @R00x061None
INC @R10x071None
INC R00x081None
INC R10x091None
INC R20x0A1None
INC R30x0B1None
INC R40x0C1None
INC R50x0D1None
INC R60x0E1None
INC R70x0F1None
INC DPTR0xA31None

INC increments the value of register by 1. If the initial value of register is 255 (0xFF Hex), incrementing the value will cause it to reset to 0. Note: The Carry Flag is NOT set when the value "rolls over" from 255 to 0.

In the case of "INC DPTR", the value two-byte unsigned integer value of DPTR is incremented. If the initial value of DPTR is 65535 (0xFFFF Hex), incrementing the value will cause it to reset to 0. Again, the Carry Flag is NOT set when the value of DPTR "rolls over" from 65535 to 0.

See Also: ADD, ADDC DEC

JB Jump if Bit Set

▸
JB bit addr, reladdr
InstructionOpCodeBytesFlags
JB bit addr,reladdr0x203None

JB branches to the address indicated by reladdr if the bit indicated by bit addr is set. If the bit is not set program execution continues with the instruction following the JB instruction.

See Also: JBC JNB

JBC Jump if Bit Set and Clear Bit

▸
JB bit addr, reladdr
InstructionOpCodeBytesFlags
JBC bit addr,reladdr0x103None

JBC will branch to the address indicated by reladdr if the bit indicated by bit addr is set. Before branching to reladdr the instruction will clear the indicated bit. If the bit is not set program execution continues with the instruction following the JBC instruction.

See Also: JB JNB

JC Jump if Carry Set

▸
JC reladdr
InstructionOpCodeBytesFlags
JC reladdr0x402None

JC will branch to the address indicated by reladdr if the Carry Bit is set. If the Carry Bit is not set program execution continues with the instruction following the JC instruction.

See Also: JNC

JMP Jump to Data Pointer + Accumulator

▸
JMP @A+DPTR
InstructionOpCodeBytesFlags
JMP @A+DPTR0x731None

JMP jumps unconditionally to the address represented by the sum of the value of DPTR and the value of the Accumulator.

See Also: LJMP AJMP SJMP

JNB Jump if Bit Not Set

▸
JNB bit addr,reladdr
InstructionOpCodeBytesFlags
JNB bit addr,reladdr0x303None

JNB will branch to the address indicated by reladdress if the indicated bit is not set. If the bit is set program execution continues with the instruction following the JNB instruction.

See Also: JB JBC

JNC Jump if Carry Not Set

▸
JNC reladdr
InstructionOpCodeBytesFlags
JNC reladdr0x502None

JNC branches to the address indicated by reladdr if the carry bit is not set. If the carry bit is set program execution continues with the instruction following the JNB instruction.

See Also: JC

JNZ Jump if Accumulator Not Zero

▸
JNZ reladdr
InstructionOpCodeBytesFlags
JNZ reladdr0x702None

JNZ will branch to the address indicated by reladdr if the Accumulator contains any value except 0. If the value of the Accumulator is zero program execution continues with the instruction following the JNZ instruction.

See Also: JZ

JZ Jump if Accumulator Zero

▸
JNZ reladdr
InstructionOpCodeBytesFlags
JZ reladdr0x602None

JZ branches to the address indicated by reladdr if the Accumulator contains the value 0. If the value of the Accumulator is non-zero program execution continues with the instruction following the JNZ instruction.

See Also: JNZ

LCALL Long Call

▸
LCALL code addr
InstructionOpCodeBytesFlags
LCALL code addr0x123None

LCALL calls a program subroutine. LCALL increments the program counter by 3 (to point to the instruction following LCALL) and pushes that value onto the stack (low byte first, high byte second). The Program Counter is then set to the 16-bit value which follows the LCALL opcode, causing program execution to continue at that address.

See Also: ACALL RET

LJMP Long Jump

▸
LJMP code addr
InstructionOpCodeBytesFlags
LJMP code addr0x023None

LJMP jumps unconditionally to the specified code addr.

See Also: AJMP SJMP JMP

MOV Move Memory

▸
MOV operand1,operand2
InstructionOpCodeBytesFlags
MOV @R0,#data0x762None
MOV @R1,#data0x772None
MOV @R0,A0xF61None
MOV @R1,A0xF71None
MOV @R0,iram addr0xA62None
MOV @R1,iram addr0xA72None
MOV A,#data0x742None
MOV A,@R00xE61None
MOV A,@R10xE71None
MOV A,R00xE81None
MOV A,R10xE91None
MOV A,R20xEA1None
MOV A,R30xEB1None
MOV A,R40xEC1None
MOV A,R50xED1None
MOV A,R60xEE1None
MOV A,R70xEF1None
MOV A,iram addr0xE52None
MOV C,bit addr0xA22C
MOV DPTR,#data160x903None
MOV R0,#data0x782None
MOV R1,#data0x792None
MOV R2,#data0x7A2None
MOV R3,#data0x7B2None
MOV R4,#data0x7C2None
MOV R5,#data0x7D2None
MOV R6,#data0x7E2None
MOV R7,#data0x7F2None
MOV R0,A0xF81None
MOV R1,A0xF91None
MOV R2,A0xFA1None
MOV R3,A0xFB1None
MOV R4,A0xFC1None
MOV R5,A0xFD1None
MOV R6,A0xFE1None
MOV R7,A0xFF1None
MOV R0,iram addr0xA82None
MOV R1,iram addr0xA92None
MOV R2,iram addr0xAA2None
MOV R3,iram addr0xAB2None
MOV R4,iram addr0xAC2None
MOV R5,iram addr0xAD2None
MOV R6,iram addr0xAE2None
MOV R7,iram addr0xAF2None
MOV bit addr,C0x922None
MOV iram addr,#data0x753None
MOV iram addr,@R00x862None
MOV iram addr,@R10x872None
MOV iram addr,R00x882None
MOV iram addr,R10x892None
MOV iram addr,R20x8A2None
MOV iram addr,R30x8B2None
MOV iram addr,R40x8C2None
MOV iram addr,R50x8D2None
MOV iram addr,R60x8E2None
MOV iram addr,R70x8F2None
MOV iram addr,A0xF52None
MOV iram addr,iram addr0x853None

MOV copies the value of operand2 into operand1. The value of operand2 is not affected. Both operand1 and operand2 must be in Internal RAM. No flags are affected unless the instruction is moving the value of a bit into the carry bit in which case the carry bit is affected or unless the instruction is moving a value into the PSW register (which contains all the program flags).

** Note: In the case of "MOV iram addr,iram addr", the operand bytes of the instruction are stored in reverse order. That is, the instruction consisting of the bytes 0x85, 0x20, 0x50 means "Move the contents of Internal RAM location 0x20 to Internal RAM location 0x50" whereas the opposite would be generally presumed.

See Also: MOVC MOVX XCH XCHD PUSH POP

MOVC Move Code Byte to Accumulator

▸
MOVC A,@A+register
InstructionOpCodeBytesFlags
MOVC A,@A+DPTR0x931None
MOVC A,@A+PC0x831None

MOVC moves a byte from Code Memory into the Accumulator. The Code Memory address from which the byte will be moved is calculated by summing the value of the Accumulator with either DPTR or the Program Counter (PC). In the case of the Program Counter, PC is first incremented by 1 before being summed with the Accumulator.

See Also: MOV MOVX

MOVX Move Data To/From External Memory (XRAM)

▸
MOVX operand1,operand2
InstructionOpCodeBytesFlags
MOVX @DPTR,A0xF01None
MOVX @R0,A0xF21None
MOVX @R1,A0xF31None
MOVX A,@DPTR0xE01None
MOVX A,@R00xE21None
MOVX A,@R10xE31None

MOVX moves a byte to or from External Memory into or from the Accumulator.

If operand1 is @DPTR, the Accumulator is moved to the 16-bit External Memory address indicated by DPTR. This instruction uses both P0 (port 0) and P2 (port 2) to output the 16-bit address and data. If operand2 is DPTR then the byte is moved from External Memory into the Accumulator.

If operand1 is @R0 or @R1, the Accumulator is moved to the 8-bit External Memory address indicated by the specified Register. This instruction uses only P0 (port 0) to output the 8-bit address and data. P2 (port 2) is not affected. If operand2 is @R0 or @R1 then the byte is moved from External Memory into the Accumulator.

See Also: MOV MOVC

MUL Multiply Accumulator by B

▸
MUL AB
InstructionOpCodeBytesFlags
MUL AB0xA41COV

Multiples the unsigned value of the Accumulator by the unsigned value of the "B" register. The least significant byte of the result is placed in the Accumulator and the most-significant-byte is placed in the "B" register.

The Carry Flag (C) is always cleared.

The Overflow Flag (OV) is set if the result is greater than 255 (if the most-significant byte is not zero), otherwise it is cleared.

See Also: DIV

NOP None, waste time

▸
No Operation
InstructionOpCodeBytesFlags
NOP0x001None

NOP, as it's name suggests, causes No Operation to take place for one machine cycle. NOP is generally used only for timing purposes. Absolutely no flags or registers are affected.

ORL Bitwise OR

▸
ORL operand1,operand2
InstructionOpCodeBytesFlags
ORL iram addr,A0x422None
ORL iram addr,#data0x433None
ORL A,#data0x442None
ORL A,iram addr0x452None
ORL A,@R00x461None
ORL A,@R10x471None
ORL A,R00x481None
ORL A,R10x491None
ORL A,R20x4A1None
ORL A,R30x4B1None
ORL A,R40x4C1None
ORL A,R50x4D1None
ORL A,R60x4E1None
ORL A,R70x4F1None
ORL C,bit addr0x722C
ORL C,/bit addr0xA02C

ORL does a bitwise "OR" operation between operand1 and operand2, leaving the resulting value in operand1. The value of operand2 is not affected. A logical "OR" compares the bits of each operand and sets the corresponding bit in the resulting byte if the bit was set in either of the original operands, otherwise the resulting bit is cleared.

See Also: ANL XRL

POP Pop Value From Stack

▸
POP
InstructionOpCodeBytesFlags
POP iram addr0xD02None

POP "pops" the last value placed on the stack into the iram addr specified. In other words, POP will load iram addr with the value of the Internal RAM address pointed to by the current Stack Pointer. The stack pointer is then decremented by 1.

See Also: PUSH

PUSH Push Value Onto Stack

▸
PUSH
InstructionOpCodeBytesFlags
PUSH iram addr0xC02None

PUSH "pushes" the value of the specified iram addr onto the stack. PUSH first increments the value of the Stack Pointer by 1, then takes the value stored in iram addr and stores it in Internal RAM at the location pointed to by the incremented Stack Pointer.

See Also: POP

RET Return From Subroutine

▸
RET
InstructionOpCodeBytesFlags
RET0x221None

RET is used to return from a subroutine previously called by LCALL or ACALL. Program execution continues at the address that is calculated by popping the topmost 2 bytes off the stack. The most-significant-byte is popped off the stack first, followed by the least-significant-byte.

See Also: LCALL ACALL RETI

RETI Return From Interrupt

▸
RETI
InstructionOpCodeBytesFlags
RETI0x321None

RETI is used to return from an interrupt service routine. RETI first enables interrupts of equal and lower priorities to the interrupt that is terminating. Program execution continues at the address that is calculated by popping the topmost 2 bytes off the stack. The most-significant-byte is popped off the stack first, followed by the least-significant-byte.

RETI functions identically to RET if it is executed outside of an interrupt service routine.

See Also: RET

RL Rotate Accumulator Left

▸
RL A
InstructionOpCodeBytesFlags
RL A0x231C

Shifts the bits of the Accumulator to the left. The left-most bit (bit 7) of the Accumulator is loaded into bit 0.

See Also: RLC RR RRC

RLC Rotate Accumulator Left Through Carry

▸
RLC A
InstructionOpCodeBytesFlags
RLC A0x331C

Shifts the bits of the Accumulator to the left. The left-most bit (bit 7) of the Accumulator is loaded into the Carry Flag, and the original Carry Flag is loaded into bit 0 of the Accumulator. This function can be used to quickly multiply a byte by 2.

See Also: RL RR RRC

RR Rotate Accumulator Right

▸
RR A
InstructionOpCodeBytesFlags
RR A0x031None

Shifts the bits of the Accumulator to the right. The right-most bit (bit 0) of the Accumulator is loaded into bit 7.

See Also: RL RLC RRC

RRC Rotate Accumulator Right Through Carry

▸
RRC A
InstructionOpCodeBytesFlags
RRC A0x131C

Shifts the bits of the Accumulator to the right. The right-most bit (bit 0) of the Accumulator is loaded into the Carry Flag, and the original Carry Flag is loaded into bit 7. This function can be used to quickly divide a byte by 2.

See Also: RL RLC RR

SETB Set Bit

▸
SETB bit addr
InstructionOpCodeBytesFlags
SETB C0xD31C
SETB bit addr0xD22None

Sets the specified bit.

See Also: CLR

SJMP Short Jump

▸
SJMP reladdr
InstructionOpCodeBytesFlags
SJMP reladdr0x802None

SJMP jumps unconditionally to the address specified reladdr. Reladdr must be within -128 or +127 bytes of the instruction that follows the SJMP instruction.

See Also: LJMP AJMP

SUBB Subtract from Accumulator With Borrow

▸
SUBB A,operand
InstructionOpCodeBytesFlags
SUBB A,#data0x942CACOV
SUBB A,iram addr0x952CACOV
SUBB A,@R00x961CACOV
SUBB A,@R10x971CACOV
SUBB A,R00x981CACOV
SUBB A,R10x991CACOV
SUBB A,R20x9A1CACOV
SUBB A,R30x9B1CACOV
SUBB A,R40x9C1CACOV
SUBB A,R50x9D1CACOV
SUBB A,R60x9E1CACOV
SUBB A,R70x9F1CACOV

SUBB subtract the value of operand and the Carry Flag from the value of the Accumulator, leaving the resulting value in the Accumulator. The value operand is not affected.

The Carry Bit (C) is set if a borrow was required for bit 7, otherwise it is cleared. In other words, if the unsigned value being subtracted is greater than the Accumulator the Carry Flag is set.

The Auxillary Carry (AC) bit is set if a borrow was required for bit 3, otherwise it is cleared. In other words, the bit is set if the low nibble of the value being subtracted was greater than the low nibble of the Accumulator.

The Overflow (OV) bit is set if a borrow was required for bit 6 or for bit 7, but not both. In other words, the subtraction of two signed bytes resulted in a value outside the range of a signed byte (-128 to 127). Otherwise it is cleared.

See Also: ADD, ADDC DEC

SWAP Swap Accumulator Nibbles

▸
SWAP A
InstructionOpCodeBytesFlags
SWAP A0xC41None

SWAP swaps bits 0-3 of the Accumulator with bits 4-7 of the Accumulator. This instruction is identical to executing "RR A" or "RL A" four times.

See Also: RL RLC RR RRC

??? Undefined Instruction

▸
???
InstructionOpCodeBytesFlags
???0xA51C

The "Undefined" instruction is, as the name suggests, not a documented instruction. The 8051 supports 255 instructions and OpCode 0xA5 is the single OpCode that is not used by any documented function. Since it is not documented nor defined it is not recommended that it be executed. However, based on research, executing this undefined instruction takes 1 machine cycle and appears to have no effect on the system except that the Carry Bit always seems to be set.

Note: input was received from an 8052.com user that the undefined instruction really has a format of Undefined bit1,bit2 and effectively copies the value of bit2 to bit1. In this case, it would be a three-byte instruction. This has not been verified or disproven, and is presented as "additional information."

Note: it has been reported that Philips 8051 model P89C669 uses instruction prefix 0xA5 to let the user access a different (extended) SFR area.

XCH Exchange Bytes

▸
XCH A,register
InstructionOpCodeBytesFlags
XCH A,@R00xC61None
XCH A,@R10xC71None
XCH A,R00xC81None
XCH A,R10xC91None
XCH A,R20xCA1None
XCH A,R30xCB1None
XCH A,R40xCC1None
XCH A,R50xCD1None
XCH A,R60xCE1None
XCH A,R70xCF1None
XCH A,iram addr0xC52None

Exchanges the value of the Accumulator with the value contained in register.

See Also: MOV

XCHD Exchange Digit

▸
XCHD A,[@R0/@R1]
InstructionOpCodeBytesFlags
XCHD A,@R00xD61None
XCHD A,@R10xD71None

Exchanges bits 0-3 of the Accumulator with bits 0-3 of the Internal RAM address pointed to indirectly by R0 or R1. Bits 4-7 of each register are unaffected.

See Also: DA

XRL Bitwise Exclusive OR

▸
XRL operand1,operand2
InstructionOpCodeBytesFlags
XRL iram addr,A0x622None
XRL iram addr,#data0x633None
XRL A,#data0x642None
XRL A,iram addr0x652None
XRL A,@R00x661None
XRL A,@R10x671None
XRL A,R00x681None
XRL A,R10x691None
XRL A,R20x6A1None
XRL A,R30x6B1None
XRL A,R40x6C1None
XRL A,R50x6D1None
XRL A,R60x6E1None
XRL A,R70x6F1None

XRL does a bitwise "EXCLUSIVE OR" operation between operand1 and operand2, leaving the resulting value in operand1. The value of operand2 is not affected. A logical "EXCLUSIVE OR" compares the bits of each operand and sets the corresponding bit in the resulting byte if the bit was set in either (but not both) of the original operands, otherwise the bit is cleared.

See Also: ANL ORL