8086 Assembly Program for Bitwise Operations: AND, OR, XOR, and NOT

This blog post will walk you through a simple 8086 assembly program designed to perform bitwise operations: AND, OR, XOR and NOT on 8-bit numbers. While these operations have a straightforward purpose, they are foundational when working at low level, manipulating bits, flags and registers. Let’s get started!

data segment
    a      db  0Ah        ; first 8-bit operand (10 decimal)
    b      db  05h        ; second 8-bit operand (5 decimal)
    res_and  db  ?        ; result of a AND b
    res_or   db  ?        ; result of a OR b
    res_xor  db  ?        ; result of a XOR b
    res_not  db  ?        ; result of NOT a
data ends

code segment
    assume cs:code, ds:data

start:
    mov ax, data
    mov ds, ax

    ; load operands into registers
    mov al, a
    mov bl, b

    ; AND operation: AL = AL AND BL
    and al, bl
    mov res_and, al

    ; reload operands for next operation
    mov al, a
    mov bl, b

    ; OR operation: AL = AL OR BL
    or al, bl
    mov res_or, al

    ; reload operands for next operation
    mov al, a
    mov bl, b

    ; XOR operation: AL = AL XOR BL
    xor al, bl
    mov res_xor, al

    ; NOT operation on first operand: AL = NOT AL
    mov al, a
    not al
    mov res_not, al

    int 3                ; breakpoint / stop for debug

code ends
end start

Understanding the Code

The program is divided into a data segment and a code segment:

Data Segment:

  • a db 0Ah: Declares an 8-bit byte variable a, initialized to 0Ah (hex) = 10 decimal.
  • b db 05h: Declares an 8-bit byte variable b, initialized to 05h (hex) = 5 decimal.
  • res_and db ?, res_or db ?, res_xor db ?, res_not db ?: Allocate bytes to store the results of the four bitwise operations.

Code Segment:

  • assume cs:code, ds:data: Tells the assembler that the cs register points to the code segment and ds points to the data segment.
  • mov ax, data / mov ds, ax: Set up the ds register so we can access our declared data variables.
  • mov al, a / mov bl, b: Load operand values into AL and BL registers.
  • and al, bl: Perform bitwise AND of AL with BL. Store result into res_and.
  • Similarly we reload a and b, then perform or al, bl and mov res_or, al.
  • Then reload again and use xor al, bl and mov res_xor, al.
  • For NOT, we only need one operand: mov al, a then not al and store via mov res_not, al.
  • int 3: A software breakpoint (useful in debugging tools) to halt execution.

High-Level Overview

  1. Data Initialization: The variables a and b are initialized with sample values. Space is allocated for the result variables.
  2. Segment Setup: The ds register is set so we can address the data segment correctly.
  3. Value Loading & Bitwise Operation: For each of the operations (AND, OR, XOR, NOT), we load operands, execute the instruction, and store the result.
  4. Program Termination: We use int 3 to halt execution for debugging.

Output

C:\TASM>masm bitops.asm
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987.  All rights reserved.
 
Object filename [bitops.OBJ]:
Source listing  [NUL.LST]:
Cross-reference [NUL.CRF]:
 
  50402 + 450254 Bytes symbol space free
 
      0 Warning Errors
      0 Severe  Errors
 
C:\TASM>link bitops.obj
 
Microsoft (R) Overlay Linker  Version 3.60
Copyright (C) Microsoft Corp 1983-1987.  All rights reserved.
 
Run File [BITOPS.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
LINK : warning L4021: no stack segment
 
C:\TASM>debug bitops.exe
-g
 
AX=0B0B  BX=0002  CX=0022  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B97  ES=0B87  SS=0B97  CS=0B98  IP=0011   NV UP EI PL NZ NA PO NC
0B98:0011 CC            INT     3
-d 0B97:0000
0B97:0000  0A 05 00 0F 0F F5 00 00-00 00 00 00 00 00 00 00   ................
0B97:0010  B8 97 0B 8E D8 A0 00 00-8A 1E 01 00 22 C3 A3 02   ................
0B97:0020  00 CC 86 72 FF 77 15 8A-86 70 FF 2A E4 50 B8 FD   ...r.w...p.*.P..
0B97:0030  05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21   .P.6$!.wc....6$!
-q

Understanding the Memory Dump

This is the memory dump starting from address 0B97:0000, showing the contents of memory. Here is the breakdown:

0B97:0000  0A 05 00 0F 0F F5 00 00-00 00 00 00 00 00 00 00 
  • 0A: The value of a = 0Ah (10 decimal)
  • 05: The value of b = 05h (5 decimal)
  • 00: The result of AND = 00h (00001010 AND 00000101 = 00000000)
  • 0F: The result of OR = 0Fh (00001010 OR 00000101 = 00001111)
  • 0F: The result of XOR = 0Fh (00001010 XOR 00000101 = 00001111)
  • F5: The result of NOT a = F5h (NOT 00001010 = 11110101)

Final Result Summary

Operationa (hex)b (hex)Result (hex)
AND0Ah05h00h
OR0Ah05h0Fh
XOR0Ah05h0Fh
NOT (a)0AhF5h

Conclusion

This simple program demonstrates how the 8086 microprocessor handles bitwise operations using register-level instructions. These operations are essential in systems programming, masking, control word manipulation, and flag management.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.