8051 Microcontroller and Assembly

This topic was published by and viewed 2954 times since "". The last page revision was "".

Viewing 1 post (of 1 total)
  • Author

  • DevynCJohnson
    • Topics - 437
    • @devyncjohnson

    The 8051 microcontroller (also called the Intel MCS-51) is a single 8-bit chip that uses the CISC instruction set and the Harvard architecture. The 8051 microcontroller is commonly used in many embedded systems due to its low-cost, low-power usage, small size, and ease of use (relative to other microcontrollers and processors). The chip itself has forty pins.

    The 8051 has many features and capabilities as listed below.

    • Multiply, divide, and compare instructions
    • 128 bytes of on-chip RAM (IRAM)
    • 4KiB of on-chip ROM
    • 16-bit (64KiB) address space (PMEM) on the ROM
    • 8-bit data bus
    • Two 16-bit address buses, program counters, and data pointers, plus related 8/11/16-bit operations
    • Boolean processor with 17 instructions
    • 8-bit ALU
    • 1-bit accumulator
    • 32 8-bit registers (four being bit-addressable)
    • One 16-bit register with special move instructions
    • Up to 144 bit-addressable RAM variables (18 bit-addressable variables each 8-bits)
    • Two 16-bit counters/timers
    • Four 8-bit/8-pin bidirectional (half-duplex) I/O ports
    • UART serial port
    • Interrupts and threads with controllable priority
    • Fast interrupts with optional register bank switching
    • Four switchable register banks each with eight memory-mapped registers
    • Power saving mode

    The 8051 microcontroller is available from many vendors. Each chip has its own part-number for each vendor and packaging as listed below. Some chips may also differ in clock-speed and available storage. The below list is not complete.

    • Atmel - 80C32E, AT48801, AT8032X2, AT80C31X2, AT80C51RD2, AT83/87C5103, AT83/87C5111, AT83/87C5112, AT83C5134, AT83C5135, AT83C5136, AT83EB5114, AT85C51SND3, AT87F51, AT87F51RC, AT87F52, AT87F55WD, AT89C1051, AT89C1051U, AT89C2051, AT89C4051, AT89C51, AT89C5115, AT89C5130, AT89C5130A, AT89C5131, AT89C5131A, AT89C5132, AT89C51AC3, AT89C51CC03, AT89C51ED2, AT89C51IC2, AT89C51ID2, AT89C51IE2, AT89C51RB2, AT89C51RC, AT89C51RC2, AT89C51RD2, AT89C51RE2, AT89C51SND1, AT89C51SND2, AT89C52, AT89C55, AT89C55WD, AT89F51, AT89F52, AT89LP2052, AT89LP213, AT89LP214, AT89LP216, AT89LP3240, AT89LP4052, AT89LP414, AT89LP428, AT89LP51, AT89LP51ED2, AT89LP51IC2, AT89LP51ID2, AT89LP51RB2, AT89LP51RC2, AT89LP51RD2, AT89LP52, AT89LP6440, AT89LP828, AT89LS51, AT89LS52, AT89LS53, AT89LS8252, AT89LV51, AT89LV52, AT89LV55, AT89S2051, AT89S4051, AT89S4D12, AT89S51, AT89S52, AT89S53, AT89S8252, AT89S8253, AT8xC5122, T80C31, T80C31X2, T80C32, T80C51, T80C51FP1, T80C51I2, T80C51RA2, T80C51RD2, T80C51U2, T83/87C51RB2, T83/87C51RC2, T83/87C51RD2, T83/87C51U2, T83/87C52X2, T83C5101, T83C5102, T87C51, T87C5101, T89C51AC2, T89C51CC01, T89C51CC02, T89C51RB2, T89C51RC2, T89C51RD2, T8xC5121, TS80C52X2, TS80C54X2, TS80C58X2
    • Infineon - C501, C501G-1R / -E, C501G-L, C504-2R /-2E, C504-L, C505-2R, C505-L, C505A-4E, C505C-2R, C505C-L, C505CA-4E, C505L-4E, C508, C509-L, C511-R, C511A-R, C513-R, C513A--2R, C513A--L, C513A--R, C513A-H, C515-1R, C515-L, C515A-4R, C515A-L, C515B-2R, C515C-8R / -8E, C515C-L, C517A-4R, C517A-L, C540U-E, C541U-2E, C868, SAB 80C515, SAB 80C515A, SAB 80C517, SAB 80C517A, SAB 80C535, SAB 80C537, SAB 83C515A-5, SAB 83C517A-5, SDA 30C16x/26x, SDA 555X TVText Pro, SDA 80D51 A-U, TLE7809, TLE7810, TLE7824, TLE7826, TLE9831, TLE9832, TLE9833, TLE9834, TLE9835, XC800, XC822-1F, XC822M-1F, XC822MT-1F, XC822T-0F, XC822T-1F, XC824M-1F, XC824MT-1F, XC835MT-2F, XC836-2F, XC836M-1F, XC836M-2F, XC836MT-1F, XC836MT-2F, XC836T-2F, XC858CA-13F, XC858CA-16F, XC858CA-9F, XC864-1FRI, XC866-1FR, XC866-2FR, XC866-4FR, XC866L-1FR, XC866L-2FR, XC866L-4FR, XC874-13F, XC874-16F, XC874CLM-13F, XC874CLM-16F, XC874CM-13F, XC874CM-16F, XC874LM-13F, XC874LM-16F, XC878-13FF, XC878-16FF, XC878C-13FF, XC878C-16FF, XC878CLM-13F, XC878CLM-16F, XC878CM-13FF, XC878CM-16FF, XC878L-13FF, XC878L-16FF, XC878LM-13F, XC878LM-16F, XC878M-13FF, XC878M-16FF, XC886-6FF, XC886-8FF, XC886C-6FF, XC886C-8FF, XC886CLM-6FF, XC886CLM-8FF, XC886CM-6FF, XC886CM-8FF, XC886LM-6FF, XC886LM-8FF, XC888-6FF, XC888-8FF, XC888C-6FF, XC888C-8FF, XC888CLM-6FF, XC888CLM-8FF, XC888CM-6FF, XC888CM-8FF, XC888LM-6FF, XC888LM-8FF
    • Maxim (formerly Dallas Semiconductor) - DS2250, DS2250T, DS2251T, DS2252T, DS5000, DS5000FP, DS5000T, DS5001FP, DS5002FP, DS5240, DS5250, DS80C310, DS80C320, DS80C323, DS80C390, DS80C400, DS80C410, DS80C411, DS87C520/DS83C520, DS87C530, DS87C550, DS89C420, DS89C430, DS89C440, DS89C450
    • Mentor Graphics - M8051ew
    • NXP - 80/87C51, 80/87C52, 80C31, 80C31X2, 80C32, 80C32X2, 80C451, 80C51FA, 80C51RA+, 80C528, 80C550, 80C552, 80C554, 80C575, 80C652, 83/87C451, 83/87C524, 83/87C528, 83/87C550, 83/87C552, 83/87C554, 83/87C575, 83/87C652, 83/87C654, 83/87C750, 83/87C751, 83/87C752, 8XC51FA/8xL51FA, 8XC51FB/8xL51FB, 8xC51FC/8xL51FC, 8xC51MA2, 8xC51MB2, 8xC51MB2/02, 8xC51MC2, 8xC51MC2/02, 8xC51RA+, 8xC51RB+, 8xC51RC+, 8xC51RD+, 8XC52, 8XC54, 8XC58, P80/P87C51X2, P80/P87C52X2, P80/P87C54X2, P80/P87C58X2, P80C557E4, P80C557E6, P80C557E8, P80C562, P80C591, P80C592, P80CE558, P80CE560, P80CE598, P80CL31, P80CL410, P80CL51, P80CL580, P83/87C654X2, P83/87C660X2, P83/87C661X2, P83/P87C557E8, P83/P87CE560, P83/P89C557E4, P83/P89CE558, P83C557E6, P83C562, P83C591, P83C592, P83CE598, P83CL410, P83CL580, P87C51FA, P87C51FB, P87C51RA2, P87C51RB2, P87C51RC2, P87C51RD2, P87C591, P87CL52X2, P87CL54X2, P87CL888, P87LPC759, P87LPC760, P87LPC761, P87LPC762, P87LPC764, P87LPC767, P87LPC768, P87LPC769, P87LPC778, P87V660X2, P89C51RA2xx, P89C51RB2Hxx, P89C51RB2xx, P89C51RC2Hxx, P89C51RC2xx, P89C51RD2Hxx, P89C51RD2xx, P89C51X2, P89C52X2, P89C54X2, P89C58X2, P89C60X2, P89C61X2, P89C660, P89C662, P89C664, P89C668, P89C669, P89C738, P89C739, P89CV51RB2, P89CV51RC2, P89CV51RD2, P89LPC779, P89LPC901, P89LPC902, P89LPC903, P89LPC904, P89LPC906, P89LPC907, P89LPC908, P89LPC9102, P89LPC9103, P89LPC9107, P89LPC912, P89LPC913, P89LPC914, P89LPC915, P89LPC916, P89LPC917, P89LPC920, P89LPC9201, P89LPC921, P89LPC9211, P89LPC922, P89LPC9221, P89LPC922A1, P89LPC924, P89LPC9241, P89LPC925, P89LPC9251, P89LPC930, P89LPC9301, P89LPC931, P89LPC9311, P89LPC931A1, P89LPC932, P89LPC9321, P89LPC932A1, P89LPC933, P89LPC9331, P89LPC934, P89LPC9341, P89LPC935, P89LPC9351, P89LPC936, P89LPC9361, P89LPC938, P89LPC9401, P89LPC9402, P89LPC9408, P89LPC952, P89LPC954, P89LPC970, P89LPC971, P89LPC972, P89LPC980, P89LPC982, P89LV51RB2, P89LV51RC2, P89LV51RD2, P89V51RB2, P89V51RC2, P89V51RD2, P89V52X2, P89V660, P89V662, P89V664, PCD6001, PCD6002, SAA5645HL, SAA5647HL, SAA5665HL, SAA5667HL, TDA8006, TDA8008, TDA8028, TDA8029
    • Silicon Labs - C8051
    • Texas Instruments - CC111x, CC24xx, CC25xx

    FUN FACT: The 8052 is binary compatible with the 8051, but the 8052 has additional features.

    The 8051 may use clock-speeds from 8MHz to 20MHz (rarely up to 450MHz) depending on the manufacturers. Originally, the chips used NMOS technology, but they are now CMOS-based. Some manufacturers use TQFP packaging, but most use the DIP chip package. Such manufacturers include Intel (the original developer), Atmel, Silicon Labs, Dallas Semiconductors, and others.

    The Harvard architecture is a computer design that uses physically independent pathways to connect the Control Unit to the data memory, instruction memory, Arithmetic Logic Unit (ALU), and Input/Output (I/O). Because of this design, the 8051 can only execute code obtained from the program memory. Also, program memory cannot be written to by the 8051 itself.

    There are four types of memory on this chip. These types include internal RAM (IRAM), special function registers (SFR), program memory (PMEM), and external data memory (XRAM). The available IRAM addresses are 0x00 to 0x7F and they can be accessed directly. The SFR is seen in the 8052, but not the 8051; SFRs are addresses 0x80 to 0xFF. PMEM may be up to 64KiB in size. XRAM can only be accessed using the MOVX (Move eXternal) instruction.

    IRAM Layout

    • 0x00–0x1F Registers R0–R7
    • 0x20–0x2F Bit-addressable

    The four ports (P0, P1, P2, and P3) can accept input and output via physical pins on the chip. Each port has eight pins. The ports are bit-addressable; specific bits are designated using a format like "P2.3" (bit 3 on P2). The command MOV P0,A sends data out (Output) while MOV A,P0 accepts/receives in-coming data (Input). Port 1 (P1) is output by default; writing "0xFF" to it makes it an input port. P2 and P3 are input ports by default; writing "0x00" to them makes them output ports. P3 is used for interrupts.

    P3 Interrupts

    • Bit/Pin Function
    • 0/10 RxD
    • 1/11 TxD
    • 2/12 INT0
    • 3/13 INT1
    • 4/14 T0
    • 5/15 T1
    • 6/16 WR
    • 7/17 RD


    All instructions are one to three bytes long. One byte being the opcode and the other two being the operands. Most (about 75%) of the opcode bytes are assigned to sixteen basic ALU instructions (listed below).

    Basic ALU Instructions

    • INC operand (0x) - Increment
    • DEC operand (1x) - Decrement
    • ADD A,operand (2x) - Add
    • ADDC A,operand (3x) - Add including the carry bit (C)
    • ORL A,operand (4x) - Logical OR
    • ANL A,operand (5x) - Logical AND
    • XRL A,operand (6x) - Logical Exclusive-OR (XOR)
    • MOV operand,#data (7x) - Move immediate data
    • MOV address,operand (8x) - Move data to an IRAM or SFR register
    • SUBB A,operand (9x) - Subtraction with borrow
    • MOV operand,address (Ax) - Move data from an IRAM or SFR register
    • CJNE operand,#data,offset (Bx) - Compare and Jump if Not Equal
    • XCH A,operand (Cx) - Exchange (switch) the accumulator and the operand
    • DJNZ operand,offset (Dx) - Decrement and Jump if Not Zero
    • MOV A,operand (Ex) - Move operand to the accumulator
    • MOV operand,A (Fx) - Move accumulator to the operand

    Notice the "x" in the opcodes' bytes. That "x" represents a variable number. Opcodes are defined by their most-significant nibble (4-bits or half a byte). The least-significant nibble specifies one of twelve addressing modes (listed below).

    • 4 - Immediate or (if no immediate) the accumulator
    • 5 - Direct Memory
    • 6 - Indirect Register (@R0)
    • 7 - Indirect Register (@R1)
    • 8 - Direct Register (R0)
    • 9 - Direct Register (R1)
    • A - Direct Register (R2)
    • B - Direct Register (R3)
    • C - Direct Register (R4)
    • D - Direct Register (R5)
    • E - Direct Register (R6)
    • F - Direct Register (R7)

    FUN FACT: Opcode "0xA5" is unused/unassigned.

    Other opcodes that are not part of the "Basic ALU Instructions" are called "Irregular Instructions". Such instructions are listed below.

    • 0x00 (NOP) - No Operation
    • 0x01 (AJMP page0) - Address Jump
    • 0x02 (LJMP addr16) - Long Jump
    • 0x03 (RR A) - Rotate Right
    • 0x04 (INC A) - Increment
    • 0x10 (JBC bit,offset) - Jump if Bit is set and then Clear the bit
    • 0x11 (ACALL page0) - Absolute Call
    • 0x12 (LCALL addr16) - Long Call
    • 0x13 (RRC A) - Rotate Right with Carry (>A C>); a rotation right where the value in A.7 becomes CY and CY becomes A.0
    • 0x14 (DEC A) - Decrement
    • 0x20 (JB bit,offset) - Jump if Bit set; jump if bit is one
    • 0x21 (AJMP page1) - Address Jump
    • 0x22 (RET) - Return; pops the high-order and low-order bytes of PC from the stack and decrements SP by two
    • 0x23 (RL A) - Rotate Left
    • 0x24 (ADD A,#data) - Addition
    • 0x30 (JNB bit,offset) - Jump if Bit Not set; jump if bit is zero
    • 0x31 (ACALL page1) - Absolute Call
    • 0x32 (RETI) - Return from Interrupt
    • 0x33 (RLC A) - Rotate Left with Carry (
    • 0x34 (ADDC A,#data) - Add including the carry bit (C)
    • 0x40 (JC offset) - Jump if the Carry bit is set (CY is "1")
    • 0x41 (AJMP page2) - Address Jump
    • 0x42 (ORL address,A) - Logical OR
    • 0x43 (ORL address,#data) - Logical OR
    • 0x44 (ORL A,#data) - Logical OR
    • 0x50 (JNC offset) - Jump if Carry Bit is Not set (CY is "0")
    • 0x51 (ACALL page2) - Absolute Call
    • 0x52 (ANL address,A) - Logical AND
    • 0x53 (ANL address,#data) - Logical AND
    • 0x54 (ANL A,#data) - Logical AND
    • 0x60 (JZ offset) - Jump if Zero
    • 0x61 (AJMP page3) - Address Jump
    • 0x62 (XRL address,A) - Logical XOR
    • 0x63 (XRL address,#data) - Logical XOR
    • 0x64 (XRL A,#data) - Logical XOR
    • 0x70 (JNZ offset) - Jump if Not Zero
    • 0x71 (ACALL page3) - Absolute Call
    • 0x72 (ORL C,bit) - Logical OR
    • 0x73 (JMP @A+DPTR) - Jump
    • 0x74 (MOV A,#data) - Move
    • 0x80 (SJMP offset) - Short Jump
    • 0x81 (AJMP page4) - Address Jump
    • 0x82 (ANL C,bit) - Logical AND
    • 0x83 (MOVC A,@A+PC) - Move a byte from code or program memory
    • 0x84 (DIV AB) - Division/Divide
    • 0x90 (MOV DPTR, #imm16) - Move
    • 0x91 (ACALL page4) - Absolute Call
    • 0x92 (MOV bit,C) - Move the value of C to bit
    • 0x93 (MOVC A,@A+DPTR) - Move a byte from code or program memory
    • 0x94 (SUBB A,#data) - Subtraction with borrow
    • 0xA0 (ORL C,bit) - Logical OR
    • 0xA1 (AJMP page5) - Address Jump
    • 0xA2 (MOV C,bit) - Move the value of bit to C
    • 0xA3 (INC DPTR) - Increment
    • 0xA4 (MUL AB) - Multiply
    • 0xB0 (ANL C,bit) - Logical AND
    • 0xB1 (ACALL page5) - Absolute Call
    • 0xB2 (CPL bit) - Logical Complement; Logical NOT; 0 becomes 1 and vice versa
    • 0xB3 (CPL C) - Logical Complement; Logical NOT; 0 becomes 1 and vice versa
    • 0xB4 (CJNE A,#data,offset) - Compare and Jump if Not Equal
    • 0xB5 (CJNE A,address,offset) - Compare and Jump if Not Equal
    • 0xC0 (PUSH address) - Increments SP
    • 0xC1 (AJMP page6) - Address Jump
    • 0xC2 (CLR bit) - Clear the specified bit (set to "0")
    • 0xC3 (CLR C) - Clear the carry bit (set to "0")
    • 0xC4 (SWAP A) - Swap the low and high nibble
    • 0xD0 (POP address) - Decrements SP
    • 0xD1 (ACALL page6) - Absolute Call
    • 0xD2 (SETB bit) - Set Bit; opposite of CLR bit; sets bit to "1"
    • 0xD3 (SETB C) - Set Bit; opposite of CLR C; sets C to "1"
    • 0xD4 (DA A) - Decimal Adjust
    • 0xD6 (XCHD A,@R0) - Exchange least-significant nibble
    • 0xD7 (XCHD A,@R1) - Exchange least-significant nibble
    • 0xE0 (MOVX A,@DPTR) - External Move
    • 0xE1 (AJMP page7) - Address Jump
    • 0xE2 (MOVX A,@R0) - External Move
    • 0xE3 (MOVX A,@R1) - External Move
    • 0xE4 (CLR A) - Clear (fill with zeros)
    • 0xF0 (MOVX @DPTR,A) - Extended Move
    • 0xF1 (ACALL page7) - Absolute Call
    • 0xF2 (MOVX @R0,A) - External Move
    • 0xF3 (MOVX @R1,A) - External Move
    • 0xF4 (CPL A) - Logical Complement; Logical NOT; 0 becomes 1 and vice versa


    Directives are pseudo-instructions (fake) that are interpreted by the assembler rather than the microcontroller.

    • DB - Define Byte; Use with labels to create constants - DATA: DB 10101010B
    • END - End of code
    • EQU - Equate; Define a constant - DATA EQU 10101010B
    • ORG address - Origin; Begin the program code at the specified address


    There are many types of registers in the 8051.

    • Stack-pointer (SP) [0x81] - 8-bit register
    • Data-pointer (DP or DPTR) [0x82 and 0x83] - 16-bit register used to access PMEM and XRAM
      • DPH - The higher 8-bits of DPTR
      • DPL - The lower 8-bits of DPTR
    • Program Status Word (PSW) [0xD0] - 8-bit register that is bit-addressable
      • PSW.0 - Parity (P); Stores the parity bit of the accumulator
      • PSW.1 - User Defined (UD)
      • PSW.2 - Overflow flag (OV); Set when addition produces a signed overflow
      • PSW.3 - Register Select 0 (RS0); Bank selection
      • PSW.4 - Register Select 1 (RS1); Bank selection
      • PSW.5 - Flag 0 (F0); Same use as PSW.1
      • PSW.6 - Auxiliary Carry (AC); Set when addition produces a carry from bit "3" to bit "4"
      • PSW.7 - Carry bit (C or CY); General carry register
    • Accumulator (A) [0xE0] - The accumulator
    • B register (B) [0xF0] - Used by the accumulator for multiplication and division instructions
    • R0 - R7 - Used to store data

    FUN FACT: The 16-bit program-counter (PC) is the only register that is not memory-mapped.


    The 8051 microcontroller is typically programmed using assembly. However, it can be programmed using BASIC, C, C++, Forth, and a few other languages.

    The assembly code uses the general pattern "LABEL: COMMAND OPERANDS ;COMMENT". However, most lines are simply "COMMAND OPERAND1,OPERAND2". Numbers are designated by the "#" symbol in the following formats (replace the "00" with the intended number).

    • #00B - Binary
    • #00 - Decimal/base-10
    • #00D - Same as "#00"
    • #00H - Hexadecimal
    • #00O - Octal

    Label names may use the characters "A-Z", "a-z", "0-9", "?", ".", "@", "_", and "$". However, the name must begin with a letter.

    Assembly (Sample Code)

    Adding two 16-bit integers on the 8-bit 8051

    ORG 0
    ;Low byte
    MOV A,#11001000b
    ADD A,#11110100b
    MOV R1,A
    ;High byte
    MOV A,#0
    ADDC A,#00000001b
    MOV R2,A
    ;Display answer
    MOV P1,R1
    MOV P2,R2

    C (Sample Code)

    Send in-coming data from P0 out to P1 or P2 (depending on the value of in-coming data)

    #include <reg51.h>
    void main(void){
        unsigned char mybyte;

    Further Reading

Viewing 1 post (of 1 total)