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
andmov 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
andmov 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
andmov 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 themove
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 Address | Hex Values | Description | Value (Hex) |
---|---|---|---|
0B97:0000 | F0 DE BC 9A | First 32-bit number (abc ) | 9ABCDEF0 |
0B97:0004 | 78 56 34 12 | Second 32-bit number (def ) | 12345678 |
0B97:0008 | 78 88 88 88 | Result of subtraction (ghi ) | 88888878 |
0B97:000C | 00 00 00 00 | Reserved/unused space | 00000000 |
“Subtracting 32-bit numbers in assembly—because using a calculator is just too mainstream!” 😆
Thank you!!
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