In this blog post, we will explore an 8086 assembly program designed to multiply two 16-bit numbers. The 8086 microprocessor, with its rich set of instructions and registers, makes it possible to perform arithmetic operations efficiently. This program demonstrates how to use the AX, BX, and DX registers to handle the multiplication process, ensuring accurate results for 16-bit operands. Let’s dive into the code and its detailed explanation!
data segment a dw 1234h b dw 5678h c dd ? data ends code segment assume ds:data, cs:code start: mov ax,data mov ds,ax mov ax,a mov bx,b mul bx mov word ptr c,ax mov word ptr c+2,dx int 3 code ends end start
“Writing an 8086 assembly program to multiply two 16-bit numbers is like teaching two toddlers to shake hands—they’ll get there eventually, but expect a lot of shifting and carrying along the way!”
Understanding the Code:
Data Segment
data segment
: This defines the beginning of the data segment where variables are stored.a dw 1234h
: Defines a 16-bit (dw
stands for “define word”) variablea
initialized to1234h
(hexadecimal).b dw 5678h
: Defines another 16-bit variableb
initialized to5678h
.c dd ?
: Defines a 32-bit (dd
stands for “define doubleword”) variablec
, which is uninitialized (?
means no initial value).
Flowchart

Code Segment
code segment
: This defines the beginning of the code segment where the instructions are stored.assume ds:data, cs:code
: Tells the assembler that the data segment register (ds
) points to thedata
segment, and the code segment register (cs
) points to thecode
segment.start
: This label marks the entry point of the program.mov ax, data
: Loads the starting address of thedata
segment into theax
register.mov ds, ax
: Transfers the address fromax
to theds
register, effectively setting up theds
register to access thedata
segment.mov ax, a
: Loads the value of variablea
(1234h
) into theax
register.mov bx, b
: Loads the value of variableb
(5678h
) into thebx
register.mul bx
: Multiplies the value inax
(froma
) by the value inbx
(fromb
). This is an unsigned multiplication.- The result of the multiplication is stored as a 32-bit value:
- The lower 16 bits are stored in
ax
. - The upper 16 bits are stored in
dx
.
- The lower 16 bits are stored in
- The result of the multiplication is stored as a 32-bit value:
mov word ptr c, ax
: Stores the lower 16 bits of the result (fromax
) into the lower part of thec
variable.mov word ptr c+2, dx
: Stores the upper 16 bits of the result (fromdx
) into the higher part of thec
variable.int 3
: Generates a software interrupt (used here to indicate program termination or for debugging purposes).code ends
: Marks the end of the code segment.end start
: Indicates the program’s entry point to the assembler.
On High Level:
- The program initializes the data segment to access variables.
- It loads the 16-bit values of
a
andb
. - It multiplies these values, producing a 32-bit result.
- The result is stored in the variable
c
:ax
contains the lower 16 bits.dx
contains the upper 16 bits.
Output
C:\TASM>masm an16mul.asm Microsoft (R) Macro Assembler Version 5.00 Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved. Object filename [an16mul.OBJ]: Source listing [NUL.LST]: Cross-reference [NUL.CRF]: 50326 + 450330 Bytes symbol space free 0 Warning Errors 0 Severe Errors C:\TASM>link an16mul.obj Microsoft (R) Overlay Linker Version 3.60 Copyright (C) Microsoft Corp 1983-1987. All rights reserved. Run File [AN16MUL.EXE]: List File [NUL.MAP]: Libraries [.LIB]: LINK : warning L4021: no stack segment C:\TASM>debug an16mul.exe -g AX=0060 BX=5678 CX=0026 DX=0626 SP=0000 BP=0000 SI=0000 DI=0000 DS=0B97 ES=0B87 SS=0B97 CS=0B98 IP=0015 OV UP EI PL NZ NA PO CY 0B98:0015 CC INT 3 -d 0B97:0000 0B97:0000 34 12 78 56 60 00 26 06-00 00 00 00 00 00 00 00 4.xV`.&......... 0B97:0010 B8 97 0B 8E D8 A1 00 00-8B 1E 02 00 F7 E3 A3 04 ................ 0B97:0020 00 89 16 06 00 CC 15 8A-86 70 FF 2A E4 50 B8 FD .........p.*.P.. 0B97:0030 05 50 FF 36 24 21 E8 77-63 83 C4 06 FF 36 24 21 .P.6$!.wc....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
0B97:0000 34 12 78 56 60 00 26 06-00 00 00 00 00 00 00 00 4.xV`.&.........
This shows the memory contents starting at address 0B97:0000
, which corresponds to the data segment. Let’s interpret the bytes:
34 12
: The value ofa
(1234h
in little-endian format).78 56
: The value ofb
(5678h
in little-endian format).60 00 26 06
: The value ofc
(result of the multiplication), stored as a 32-bit number:60 00
: Lower 16 bits of the result (AX
).26 06
: Upper 16 bits of the result (DX
).
00 00 00 00 ...
: Remaining memory space, currently unused or initialized to zero.
Multiplication Breakdown
The program multiplies a = 1234h
and b = 5678h
.
Unsigned Multiplication:
1234h×5678h=06266060h
- Result (32-bit):
- Lower 16 bits (
AX
):0060h
. - Upper 16 bits (
DX
):0626h
.
- Lower 16 bits (
These values are stored in the c
variable, as confirmed by the memory dump.