8086 Assembly Program for Subtraction of Two 32 bit Numbers

​In this blog post, we’ll explore how to perform the subtraction of two 32-bit numbers using an 8086 assembly language program. Handling 32-bit arithmetic operations on the 16-bit 8086 microprocessor requires managing carries between the lower and upper words of the numbers. Let’s delve into the implementation.​

data segment
abc dd 9ABCDEF0h
def dd 12345678h
ghi dw ?
data ends

code segment
assume cs:code, ds:data
start:
mov ax,data
mov ds,ax
mov dl,00h
mov ax, word ptr abc
mov bx, word ptr def
sub ax,bx
mov word ptr ghi,ax
mov ax, word ptr abc+2
mov bx, word ptr def+2
sbb ax,bx
mov word ptr ghi+2,ax
jnc move
inc dl
move: mov byte ptr ghi+4,dl
int 3
code ends
end start

Step-by-Step Explanation:

1. Data Segment

  • abc: Defines the first 32-bit number (0x9ABCDEF0).
  • def: Defines the second 32-bit number to subtract from the first (0x12345678).​
  • ghi: Reserves space to store the 32-bit result of the subtraction.

2. Code Segment

Initialization:

  • mov ax, data and mov ds, ax: Initialize the data segment register to access the data segment.​
  • mov dl, 00h: Initialize the DL register to 0; this will be used to store the carry (borrow) flag.​

Subtract Lower Words:

  • mov ax, word ptr abc and mov bx, word ptr def: Load the lower 16 bits of the numbers into AX and BX registers, respectively.​
  • sub ax, bx: Subtract BX from AX.​
  • mov word ptr ghi, ax: Store the result of the lower word subtraction into the lower word of the result (ghi).​

Subtract Upper Words with Borrow:

  • mov ax, word ptr abc+2 and mov bx, word ptr def+2: Load the upper 16 bits of the numbers into AX and BX registers, respectively.​
  • sbb ax, bx: Subtract BX from AX with borrow (if there was a borrow from the lower word subtraction).​
  • mov word ptr ghi+2, ax: Store the result of the upper word subtraction into the upper word of the result (ghi).​

Handle Borrow:

  • jnc move: If there’s no carry (borrow), jump to the move label.​
  • inc dl: If there’s a borrow, increment DL to indicate this.​

Store Borrow Flag:

  • mov byte ptr ghi+4, dl: Store the value of DL (borrow flag) into the byte following the result.​

Terminate Program:

  • int 3: Interrupt to terminate the program.

Flowchart:

Overall Process:

  • The program initializes two 32-bit numbers in memory.
  • It loads the lower 16 bits of both numbers and performs subtraction.
  • The result of the lower word subtraction is stored in memory.
  • It then loads the upper 16 bits of both numbers and subtracts them, including any borrow from the lower word.
  • The result of the upper word subtraction is stored in memory.
  • If there was a borrow during subtraction, it updates a flag to indicate it.
  • The borrow flag is stored in memory for reference.
  • The program terminates.

Output

C:\TASM>masm an32sub.asm
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987.  All rights reserved.
 
Object filename [an32sub.OBJ]:
Source listing  [NUL.LST]:
Cross-reference [NUL.CRF]:
 
  50288 + 450368 Bytes symbol space free
 
      0 Warning Errors
      0 Severe  Errors
 
C:\TASM>link an32sub.obj
 
Microsoft (R) Overlay Linker  Version 3.60
Copyright (C) Microsoft Corp 1983-1987.  All rights reserved.
 
Run File [AN32SUB.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
LINK : warning L4021: no stack segment
 
C:\TASM>debug an32sub.exe
-g
 
AX=8888  BX=1234  CX=0038  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B97  ES=0B87  SS=0B97  CS=0B98  IP=0027   NV UP EI NG NZ NA PE NC
0B98:0027 CC            INT     3
-d 0B97:0000
0B97:0000  F0 DE BC 9A 78 56 34 12-78 88 88 88 00 00 00 00   ....xV4.x.......
0B97:0010  B8 97 0B 8E D8 B2 00 A1-00 00 8B 1E 04 00 2B C3   ..............+.
0B97:0020  A3 08 00 A1 02 00 8B 1E-06 00 1B C3 A3 0A 00 73   ...............s
0B97:0030  02 FE C2 88 16 0C 00 CC-63 83 C4 06 FF 36 24 21   ........c....6$!
0B97:0040  B8 0A 00 50 E8 47 5E 83-C4 04 5E 8B E5 5D C3 90   ...P.G^...^..]..
0B97:0050  55 8B EC 81 EC 84 00 C4-5E 04 26 80 7F 0A 00 74   U.......^.&....t
0B97:0060  3E 8B 46 08 8B 56 0A 89-46 FC 89 56 FE C4 5E FC   >.F..V..F..V..^.
0B97:0070  26 8A 47 0C 2A E4 40 50-8B C3 05 0C 00 52 50 E8   &.G.*[email protected].
-q

Understanding the Memory Dump

The memory dump shows the data and code stored in memory after running the 8086 assembly program for subtracting two 32-bit numbers.

Refer the Data Segment (0B97:0000)

0B97:0000  F0 DE BC 9A 78 56 34 12-78 88 88 88 00 00 00 00   ....xV4.x.......

Memory AddressHex ValuesDescriptionValue (Hex)
0B97:0000F0 DE BC 9AFirst 32-bit number (abc)9ABCDEF0
0B97:000478 56 34 12Second 32-bit number (def)12345678
0B97:000878 88 88 88Result of subtraction (ghi)88888878
0B97:000C00 00 00 00Reserved/unused space00000000

“Subtracting 32-bit numbers in assembly—because using a calculator is just too mainstream!” 😆

2 thoughts on “8086 Assembly Program for Subtraction of Two 32 bit Numbers”

  1. Doesn’t work in the case of smaller number – larger number:

    ; 32 bit subtraction
    ; _______________

    assume cs:code, ds:data

    data segment
    opr1 dd 0ffffffffh
    opr2 dd 00000001h
    res dd 00000000h
    car db 00h
    data ends

    code segment
    org 0100h

    start: mov ax, data
    mov ds, ax
    mov ch, 00h
    mov ax, word ptr opr1
    mov bx, word ptr opr2
    sub ax, bx
    jnc here1
    neg ax

    here1: mov word ptr res, ax
    mov ax, word ptr opr1 + 2
    mov bx, word ptr opr2 + 2
    sbb ax, bx
    jnc here2
    neg ax
    inc ch

    here2: mov word ptr res+2, ax
    mov byte ptr res+4, ch
    mov ah, 4ch
    int 21h

    code ends

    end start

Leave a Reply

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