× back

Assembly Language Programming (8085)

Assembly language programming for the 8085 microprocessor involves writing low-level code that directly controls the hardware. This type of programming is essential for understanding how microprocessors work, optimizing performance, and implementing critical real-time applications. The 8085 microprocessor, with its simple architecture and instruction set, is an excellent starting point for learning assembly language programming.

Instruction Set

The instruction set of the 8085 microprocessor comprises various commands that dictate the processor's operations. These instructions are categorized into five main groups, each serving a distinct purpose:

  1. Data Transfer Group
  2. Arithmetic Group
  3. Logical Group
  4. Branch Control Group
  5. Control Group

Data Transfer Group

The Data Transfer Group includes instructions that handle the movement of data between registers, memory, and I/O devices. These instructions are crucial for the effective manipulation of data within the system.

The addressing modes in this group specify how the operand is accessed. One of the most common modes is the Immediate Mode, where the operand is included directly in the instruction, enabling rapid execution without delay.

Here are some key instructions under the immediate addressing mode:

  1. MVI B, 25H:
    The "MVI" instruction stands for "Move Immediate," indicating that the data (25H) is moved directly into the specified register (B).
    Format: MVI [destination], [source]
    Operation: B ← 25H
    Explanation: This instruction places the hexadecimal value 25 directly into the B register. The "I" in "MVI" signifies that the operand is immediate, meaning it is provided directly in the instruction itself.
  2. LXI B, 2000H:
    The "LXI" instruction stands for "Load Register Pair Immediate," indicating that the data (2000H) is loaded directly into a specified register pair.
    Format: LXI [register pair], [data]
    Operation: B ← 20H, C ← 00H
    Explanation: This instruction loads the immediate 16-bit data (2000H) into the B-C register pair. Here, the higher byte (20H) is loaded into register B, and the lower byte (00H) is loaded into register C. The "X" in "LXI" denotes that the instruction deals with a register pair.
  3. MVI M, 25H:
    In this instruction, "M" stands for memory. The memory location is defined by the address pointed to by the H-L register pair.
    Format: MVI M, [data]
    Operation: (HL) ← 25H
    Explanation: This instruction loads the immediate value 25H into the memory location pointed to by the H-L register pair. For instance, if the H-L pair is pointing to the memory address C500, the value 25H will be stored at that specific memory location. The use of "M" indicates that the data is being moved directly into the memory address defined by the contents of the H-L register pair.

Now we have the Register Addressing Mode. In this mode, data is transferred through registers. The following instructions fall under this category:

  1. MOV B, C:
    This instruction moves the data from register C to register B.
    Format: MOV [destination], [source]
    Operation: B ← C
    Explanation: The data in register C is transferred to register B. This operation is useful when you need to copy data between registers without altering the original data in the source register (C in this case).
  2. MOV B, M:
    This instruction moves the data from the memory location addressed by the H-L register pair to register B.
    Format: MOV [destination], [source]
    Operation: B ← (HL)
    Explanation: The data in the memory location pointed to by the H-L register pair is transferred to register B. This instruction is useful for accessing data stored in memory and moving it to a register for further processing.
  3. MOV M, C:
    This instruction moves the data from register C to the memory location addressed by the H-L register pair.
    Format: MOV [destination], [source]
    Operation: (HL) ← C
    Explanation: The data in register C is transferred to the memory location specified by the H-L register pair. This instruction is useful for storing data from a register into a specific memory address for later use. For instance, if the H-L pair points to the memory address 3000H, the data in register C will be moved to this address.

Now the following instructions come under the high-level instructions:

  1. LDA 2000H:
    This instruction loads the accumulator with the data from the memory location 2000H.
    Format: LDA [address]
    Operation: A ← (2000H)
    Explanation: The "LDA" instruction stands for "Load Accumulator." Although the accumulator (A) is an 8-bit register, the address 2000H is 16-bit, indicating the location in memory from which data is to be fetched. This instruction reads the data from the specified memory address (2000H) and loads it into the accumulator for immediate use in subsequent operations.
  2. STA 2000H:
    This instruction stores the contents of the accumulator into the memory location 2000H.
    Format: STA [address]
    Operation: (2000H) ← A
    Explanation: The "STA" instruction stands for "Store Accumulator." It takes the data in the accumulator and writes it to the specified memory address. For instance, if the accumulator contains the value 5AH, executing STA 2000H will store this value at the memory location 2000H.
  3. LDAX B:
    This instruction loads the accumulator with the contents of the memory location addressed by the B-C register pair.
    Format: LDAX [register pair]
    Operation: A ← (BC)
    Explanation: The "LDAX" instruction stands for "Load Accumulator Indirect." It fetches data from the memory address specified by the B-C register pair and loads it into the accumulator. If the B-C register pair points to address 3000H, executing LDAX B will load the data from memory location 3000H into the accumulator.
  4. STAX B:
    This instruction stores the contents of the accumulator into the memory location addressed by the B-C register pair.
    Format: STAX [register pair]
    Operation: (BC) ← A
    Explanation: The "STAX" instruction stands for "Store Accumulator Indirect." It takes the data in the accumulator and writes it to the memory address specified by the B-C register pair. If the accumulator contains the value 3FH and the B-C pair points to address 4000H, executing STAX B will store 3FH at memory location 4000H.

Arithmetic Group

The Arithmetic Group includes instructions that perform various arithmetic operations such as addition, subtraction, multiplication, and division.

We have the following instructions:

  1. ADD B:
    In microprocessor instructions, the operand is fixed to register A, so it does not need to be included in the instruction, resulting in a shorter instruction length.
    Operation: A ← A + B
    Explanation: This instruction adds the contents of register B to register A, updating the value in register A with the sum.
  2. ADD M:
    Here, M represents a memory location where data is stored.
    Operation: A ← A + [data at memory location M]
    Explanation: This instruction adds the data stored at memory location M to the contents of register A, updating the value in register A with the sum.
    H and L Pair: In some microprocessor architectures like Intel 8085, the `ADD M` instruction indirectly uses the H and L registers. The memory address specified by the HL pair (H-L register pair) points to the memory location M. So, the data at the memory location addressed by HL is added to register A.
  3. SUB B:
    This instruction subtracts the value in register B from the contents of register A.
    Operation: A ← A - B
    Explanation: The SUB B instruction performs subtraction by subtracting the value in register B from the contents of register A, updating the result in register A.
  4. SUB M:
    Here, M represents a memory location where data is stored.
    Operation: A ← A - [data at memory location M]
    Explanation: This instruction subtracts the data stored at memory location M from the contents of register A, updating the value in register A with the difference.
    H and L Pair: Similar to the ADD M instruction, in architectures like Intel 8085, the `SUB M` instruction indirectly uses the H and L registers. The memory address specified by the HL pair (H-L register pair) points to the memory location M, from which data is subtracted from register A.
  5. INR B:
    This instruction increments the value in register B by 1.
    Operation: B ← B + 1
    Explanation: The INR B instruction increases the value in register B by 1, updating the result in register B.
  6. DCR B:
    This instruction decrements the value in register B by 1.
    Operation: B ← B - 1
    Explanation: The DCR B instruction decreases the value in register B by 1, updating the result in register B.
  7. INR M:
    Here, M represents a memory location where data is stored.
    Operation: [data at memory location M] ← [data at memory location M] + 1
    Explanation: This instruction increments the data stored at memory location M by 1, updating the value at that memory location.
    H and L Pair: In architectures like Intel 8085, the `INR M` instruction indirectly uses the H and L registers. The memory address specified by the HL pair (H-L register pair) points to the memory location M, where data is incremented by 1.
  8. DCR M:
    Here, M represents a memory location where data is stored.
    Operation: [data at memory location M] ← [data at memory location M] - 1
    Explanation: This instruction decrements the data stored at memory location M by 1, updating the value at that memory location.
    H and L Pair: Similar to `INR M`, the `DCR M` instruction in certain architectures indirectly uses the H and L registers to access and modify data at memory location M.
  9. INX B:
    This instruction increments the BC register pair by 1.
    Operation: BC ← BC + 1
    Explanation: The INX B instruction increases the BC register pair by 1, updating the result in the BC register pair.
  10. DCX B:
    This instruction decrements the BC register pair by 1.
    Operation: BC ← BC - 1
    Explanation: The DCX B instruction decreases the BC register pair by 1, updating the result in the BC register pair.
  11. CMP B (Compare with Register B):
    In microprocessor instructions, the CMP B instruction compares the contents of the accumulator with the contents of register B.
    Operation: A - B
    Explanation: This instruction subtracts the contents of register B from the contents of the accumulator, but the result is not stored. Instead, the flags are updated based on the result of the subtraction.
    • If the accumulator is greater than the contents of register B, the carry flag (CY) is reset (CY = 0) and the zero flag (Z) is reset (Z = 0).
    • If the accumulator is equal to the contents of register B, the zero flag (Z) is set (Z = 1).
    • If the accumulator is less than the contents of register B, the carry flag (CY) is set (CY = 1).

Branch Control Group

The Branch Control Group in the 8085 microprocessor contains instructions that change the sequence of execution of instructions in a program. These instructions are essential for implementing control flow constructs such as loops, conditionals, and function calls. The primary function of branch control instructions is to alter the program counter (PC), which dictates the address of the next instruction to be executed.

  1. JNC (Jump if No Carry):
    In microprocessor instructions, the condition is checked for the Carry flag (CY). If the CY flag is not set (no carry occurred), the program jumps to the specified address or label.
    Operation: Conditional jump to specified address if CY flag is not set (no carry occurred).
    Explanation: This instruction checks the Carry flag (CY) and jumps to the specified address or label if the CY flag is not set (indicating no carry occurred during the previous operation). Otherwise, the program continues sequential execution without jumping.
  2. RCC (Return on Carry Clear):
    In microprocessor instructions, the condition is checked for the Carry flag (CY). If the CY flag is not set (no carry occurred), the program returns from the subroutine to the address stored in the stack.
    Operation: Conditional return from subroutine if CY flag is not set (no carry occurred).
    Explanation: This instruction checks the Carry flag (CY) and returns from the subroutine to the address stored in the stack if the CY flag is not set (indicating no carry occurred during the previous operation). Otherwise, the program continues sequential execution within the subroutine.

Control Group

The Control Group in the 8085 microprocessor includes instructions that manage the flow of data and control within the processor. These instructions are crucial for handling input/output operations, enabling interrupts, and controlling various aspects of the microprocessor's operation.

  1. HLT (Halt):
    In microprocessor instructions, the HLT instruction is used to halt or stop the execution of the program.
    Operation: Halts the program execution.
    Explanation: This instruction causes the microprocessor to stop executing instructions and enter a halted state, suspending program execution until the system is reset or another interrupt occurs.

There are many instructions, about 70 or more, but we are only discussing those that are relevant for writing basic assembly language programs.

Categorization of Microprocessor Instructions by Byte Length

As we will write programs in assembly language, it is important to know the byte length of the instructions so that we can accurately fill the memory location column of our program.

One-Byte Instructions

One-byte instructions consist solely of an opcode and operate directly on specific registers or implied operands. They do not require any additional data bytes.

  • MOV B, C: Moves the contents of register C to register B.
  • MOV B, M: Moves the contents of the memory location pointed to by the HL register pair to register B.
  • MOV M, C: Moves the contents of register C to the memory location pointed to by the HL register pair.
  • LDAX B: Loads the contents of the memory location pointed to by the BC register pair into the accumulator.
  • STAX B: Stores the contents of the accumulator in the memory location pointed to by the BC register pair.
  • ADD B: Adds the contents of register B to the accumulator.
  • ADD M: Adds the contents of the memory location pointed to by the HL register pair to the accumulator.
  • SUB B: Subtracts the contents of register B from the accumulator.
  • SUB M: Subtracts the contents of the memory location pointed to by the HL register pair from the accumulator.
  • INR B: Increments the contents of register B by 1.
  • DCR B: Decrements the contents of register B by 1.
  • INR M: Increments the contents of the memory location pointed to by the HL register pair by 1.
  • DCR M: Decrements the contents of the memory location pointed to by the HL register pair by 1.
  • INX B: Increments the BC register pair by 1.
  • DCX B: Decrements the BC register pair by 1.

Two-Byte Instructions

Two-byte instructions consist of an opcode followed by a single byte of data. This additional byte provides immediate data or an 8-bit operand.

  • MVI B, 25H: Moves immediate data 25H to register B.
    First byte: Opcode for MVI B.
    Second byte: Immediate data 25H.
  • MVI M, 25H: Moves immediate data 25H to the memory location pointed to by the HL register pair.
    First byte: Opcode for MVI M.
    Second byte: Immediate data 25H.
  • JNC (Jump if No Carry): Conditional jump instruction in the 8085 microprocessor instruction set.
    First byte: Opcode for JNC.
    Second byte: Address or label to jump to if the Carry flag (CY) is not set (no carry occurred).

Three-Byte Instructions

Three-byte instructions consist of an opcode followed by two bytes of data. These two bytes typically represent a 16-bit address.

  • LXI B, 2000H: Loads the BC register pair with immediate 16-bit data 2000H.
    First byte: Opcode for LXI B.
    Second byte: Lower-order byte of the address (00H).
    Third byte: Higher-order byte of the address (20H).
  • LDA 2000H: Loads the accumulator with the contents of memory location 2000H.
    First byte: Opcode for LDA.
    Second byte: Lower-order byte of the address (00H).
    Third byte: Higher-order byte of the address (20H).
  • STA 2000H: Stores the contents of the accumulator in memory location 2000H.
    First byte: Opcode for STA.
    Second byte: Lower-order byte of the address (00H).
    Third byte: Higher-order byte of the address (20H).

Assembly Language Programs

1- Write a Program for Addition of two 8-bit Hexa-decimal Numbers and Store the Result at 3050H Location. (Without Carry)

Suppose the first number is 32H and the second number is 54H. The addition of these two numbers will be 32H + 54H = 86H.
We start our program from the memory location 3000H, so 3000H will be the starting memory location.

                    
Memory Location  |   Instruction   |    Comments
-----------------|-----------------|---------------------------------------------
  3000H          |  MVI A, 32H     |    ; Load 32H into the accumulator (A)
  3002H          |  MVI B, 54H     |    ; Load 54H into register B
  3004H          |  ADD B          |    ; Add the contents of register B to the accumulator
  3005H          |  STA 3050H      |    ; Store the result from the accumulator at memory location 3050H
  3008H          |  HLT            |    ; Halt the program
                    
                

Explanation of Instructions:

  • MVI A, 32H: This instruction moves the immediate value 32H into the accumulator (A).
  • MVI B, 54H: This instruction moves the immediate value 54H into register B.
  • ADD B: This instruction adds the contents of register B to the accumulator and stores the result in the accumulator.
  • STA 3050H: This instruction stores the contents of the accumulator at the memory location 3050H.
  • HLT: This instruction halts the execution of the program.

2. Write a Program for Addition of Two 8-bit Hexadecimal Numbers and Store the Sum and Carry at Memory Locations 2051H and 2052H Respectively

Numbers are: FFH and FFH.

So basically, FFH is added to FFH, resulting in 1FEH. Since there is a carry, 1 is stored as the carry, and FEH is stored as the sum.

The basic steps involved for this program are:

  1. Start
  2. Initialize the carry register as zero (C = 0)
  3. Get the first and second numbers
  4. Add them
  5. Check for the carry
    • If there is a carry, then increment the carry register
  6. Store the sum
  7. Store the carry if there is one
  8. Stop
                    
MVI C, 00H        ; Initialize carry register (C) to zero
MVI A, FFH        ; Load first number (FFH) into accumulator A
MVI B, FFH        ; Load second number (FFH) into register B
ADD B             ; Add the contents of register B to accumulator A
JNC NO_CARRY      ; Jump if no carry (CY flag is not set)
INR C             ; Increment register C (carry) by 1 if there is a carry
NO_CARRY:         ; Label for no carry condition
STA 2051H         ; Store the sum from the accumulator to memory location 2051H
MOV A, C          ; Move the value of register C (carry) to accumulator A
STA 2052H         ; Store the carry from the accumulator to memory location 2052H
HLT               ; Halt the program
                    
                

After execution of this program, FEH will be stored at 2051H, and the carry 1 will be stored at 2052H.

3- Program to Subtract Two 8-Bit Numbers Without Borrow in 8085

Suppose we have two 8-bit numbers, 40H and 30H, and we want to subtract them without borrow.

    
  Memory Location  |   Instruction   |    Comments
-------------------|-----------------|---------------------------------------------
    3000H          |  MVI A, 40H     |    ; Load first number (40H) into accumulator A
    3002H          |  MVI B, 30H     |    ; Load second number (30H) into register B
    3004H          |  SUB B          |    ; Subtract the content of register B from accumulator A without borrow
    3005H          |  HLT            |    ; Halt the program
    

Explanation of Instructions:

  • MVI A, 40H: Load the first number (40H) into accumulator A.
  • MVI B, 30H: Load the second number (30H) into register B.
  • SUB B: Subtract the content of register B from accumulator A without borrow.
  • HLT: Halt the execution of the program.

4- Program to Subtract Two 8-Bit Numbers with Borrow in 8085

Suppose we have two 8-bit numbers, 30H and 20H where we want to subtract 30H from 20H with borrow (20H - 30H).

    
  Memory Location  |   Instruction   |    Comments
-------------------|-----------------|---------------------------------------------
    3000H          |  MVI A, 20H     |    ; Load 20H into accumulator A
    3002H          |  MVI B, 30H     |    ; Load 30H into register B
    3004H          |  SUB B          |    ; Subtract B from A with borrow
    3005H          |  MOV C, A       |    ; Move result to register C
    3006H          |  SBB A          |    ; Subtract borrow from A
    3007H          |  HLT            |    ; Halt the program
    

Explanation:

  • MVI A, 20H: Loads the first number (20H) into accumulator A.
  • MVI B, 30H: Loads the second number (30H) into register B.
  • SUB B: Subtracts B (30H) from A (20H) with borrow.

Now, let's perform the binary subtraction:

  A (Accumulator)  |  B (Register B)  |  Result (A - B with borrow)  |  Carry (CY)  
-------------------|------------------|-----------------------------|---------------
    0010 0000      |    0011 0000     |          1111 0000           |       1       

After the subtraction, the result (1111 0000) is stored in accumulator A, and the carry flag (CY) is set to 1 indicating a borrow.

  • MOV C, A: Moves the result (1111 0000) from accumulator A to register C.
  • SBB A: Subtracts the borrow (1) from A (1111 0000 - 1 = 1110 1111).
  • HLT: Halts the program.

After executing this program, the final result in accumulator A is EFH (1110 1111 in binary).

5- Program to Add Two 16-bit Hexadecimal Numbers and Store the Result at Memory Location 3050H

Suppose we have two 16-bit numbers: 2A75H and B42FH. We want to add these numbers and store the result at memory location 3050H.

    
Memory Location  |   Instruction   |    Comments
-----------------|-----------------|---------------------------------------------
    3000H        |  MVI H, 2AH     |    ; Load high byte of first number (2A75H) into register H
    3002H        |  MVI L, 75H     |    ; Load low byte of first number into register L
    3004H        |  MVI D, B4H     |    ; Load high byte of second number (B42FH) into register D
    3006H        |  MVI E, 2FH     |    ; Load low byte of second number into register E
    3008H        |  MOV A, L       |    ; Move low byte of first number to accumulator A
    3009H        |  ADD E          |    ; Add low byte of second number to accumulator A
    300AH        |  MOV L, A       |    ; Move the sum in accumulator A to register L (low byte)
    300BH        |  MOV A, H       |    ; Move high byte of first number to accumulator A
    300CH        |  ADC D          |    ; Add high byte of second number to accumulator A with carry
    300DH        |  MOV H, A       |    ; Move the sum in accumulator A to register H (high byte)
    300EH        |  STA 3050H      |    ; Store the 16-bit sum from registers H and L at memory location 3050H
    3011H        |  HLT            |    ; Halt the program
    

Explanation of Instructions:

  • MVI H, 2AH: Load the high byte (2A) of the first number (2A75H) into register H.
  • MVI L, 75H: Load the low byte (75) of the first number into register L.
  • MVI D, B4H: Load the high byte (B4) of the second number (B42FH) into register D.
  • MVI E, 2FH: Load the low byte (2F) of the second number into register E.
  • MOV A, L: Move the low byte of the first number (75) to accumulator A.
  • ADD E: Add the low byte of the second number (2F) to accumulator A (resulting in 75 + 2F = A4).
  • MOV L, A: Move the sum (A4) in accumulator A to register L (low byte).
  • MOV A, H: Move the high byte (2A) of the first number to accumulator A.
  • ADC D: Add the high byte (B4) of the second number to accumulator A with carry (resulting in 2A + B4 + 1 (carry) = D9).
  • MOV H, A: Move the sum (D9) in accumulator A to register H (high byte).
  • STA 3050H: Store the 16-bit sum (D9A4H) from registers H and L at memory location 3050H.
  • HLT: Halt the execution of the program.

6- Program to Swap Two Numbers in Memory Locations.

Suppose we have two numbers stored in memory locations 4000H and 4001H, and we want to swap their values.

                                
Memory Location  |   Instruction   |    Comments
-----------------|-----------------|---------------------------------------------
    3000H        |  LXI H, 4000H   |    ; Load memory location for first number into register pair HL
    3003H        |  MOV A, M       |    ; Move the content of memory location 4000H to accumulator A
    3004H        |  LXI D, 4001H   |    ; Load memory location for second number into register pair DE
    3007H        |  MOV E, M       |    ; Move the content of memory location 4001H to register E
    3008H        |  MOV L, E       |    ; Move the content of register E (second number) to register L (first number)
    3009H        |  MOV M, A       |    ; Move the content of accumulator A (first number) to memory location 4001H
    300AH        |  MOV M, L       |    ; Move the content of register L (second number) to memory location 4000H
    300BH        |  HLT            |    ; Halt the program
                                
                            

Explanation of Instructions:

  • LXI H, 4000H: Load the memory location for the first number into register pair HL.
  • MOV A, M: Move the content of memory location 4000H to accumulator A.
  • LXI D, 4001H: Load the memory location for the second number into register pair DE.
  • MOV E, M: Move the content of memory location 4001H to register E.
  • MOV L, E: Move the content of register E (second number) to register L (first number).
  • MOV M, A: Move the content of accumulator A (first number) to memory location 4001H.
  • MOV M, L: Move the content of register L (second number) to memory location 4000H.
  • HLT: Halt the execution of the program.

7- Program to Move a Block of Data of 16 Bytes from Starting Addresses 2050H to 2060H in 8085

We want to move a block of data of 16 bytes from starting addresses 2050H to 2060H to another location.

                                
Memory Location  |   Instruction   |    Comments
-----------------|-----------------|---------------------------------------------
    3000H          |  LXI H, 2050H   |    ; Load starting address of the block into register pair HL
    3003H          |  LXI D, 2070H   |    ; Load destination address into register pair DE
    3006H          |  LXI B, 10H     |    ; Load counter (number of bytes to move) into register pair BC
    3009H          |  L1 MOV A, M    |    ; Move data from source address pointed by HL to accumulator A
    300AH          |  MOV M, A       |    ; Move data from accumulator A to destination address pointed by DE
    300BH          |  INX H          |    ; Increment source address (HL)
    300CH          |  INX D          |    ; Increment destination address (DE)
    300DH          |  DCX B          |    ; Decrement counter (BC)
    300EH          |  JNZ L1         |    ; Jump to L1 if counter is not zero
    3011H          |  HLT            |    ; Halt the program
                                
                            

Explanation of Instructions:

  • LXI H, 2050H: Load the starting address of the block (2050H) into register pair HL.
  • LXI D, 2070H: Load the destination address (2070H) into register pair DE.
  • LXI B, 10H: Load the counter (number of bytes to move, here 16 bytes) into register pair BC.
  • MOV A, M: Move data from the source address pointed by HL to accumulator A.
  • MOV M, A: Move data from accumulator A to the destination address pointed by DE.
  • INX H: Increment the source address (HL).
  • INX D: Increment the destination address (DE).
  • DCX B: Decrement the counter (BC).
  • JNZ L1: Jump to label L1 if the counter is not zero.
  • HLT: Halt the execution of the program.

Reference