8-bit division in 8086 assembly has a subtle but important difference from 16-bit division: the dividend is always the full 16-bit AX register, not just AL. When you write DIV b with a byte operand, the CPU divides the 16-bit value in AX by that byte — quotient lands in AL, remainder in AH. Getting AH cleared to zero before the divide is therefore essential for a correct result. This post walks through a working implementation in three environments: MASM/TASM, emu8086, and NASM.
Prerequisites: Familiarity with 8086 registers and the segment setup pattern. Read Understanding DW and DB in 8086 Assembly first if you are new to assembly.
The Problem: Dividing 28h by 02h
We want to divide 28h (40 decimal) by 02h (2 decimal) and store the result. Quick check: 40 ÷ 2 = 20 = 14h, remainder 0. The debugger confirms AX=0014 (AH=00 remainder, AL=14h quotient) ✓.
AX as the dividend — not just AL. Quotient → AL, Remainder → AH. This means if AH contains leftover garbage before the divide, the effective dividend is wrong. Always clear AH (with xor ah, ah or mov ah, 0) or zero the entire AX (with mov ax, 0) before loading AL with your dividend.
Version 1 — MASM / TASM (Classic DOS Toolchain)
data segment
a db 28h ; 8-bit dividend (40 decimal)
b db 02h ; 8-bit divisor (2 decimal)
c dw ? ; 16-bit result: AL=quotient, AH=remainder
data ends
code segment
assume cs:code, ds:data
start:
mov ax, data ; Load data segment address
mov ds, ax ; Initialize DS
mov ax, 0000h ; Clear AX entirely (AH=0 is critical for 8-bit DIV)
mov al, a ; Load dividend into AL (AX = 0028h)
div b ; AX / b: AL = quotient (14h), AH = remainder (00h)
mov c, ax ; Store quotient in AL, remainder in AH, both into c
int 3 ; Halt for debugging
code ends
end start
mov bl, b and then calls div b (a memory operand). The BL load is wasted — div b reads the divisor directly from memory, completely ignoring BL. Many students then change it to div bl thinking it is equivalent, but div bl uses the register while div b uses memory; both happen to hold 02h here, so the result is the same, but the code is cleaner without the unnecessary BL load.
Related Links:
Step-by-Step Explanation
1. Data Segment
a db 28h: Defines the 8-bit dividend (40 decimal).b db 02h: Defines the 8-bit divisor (2 decimal).c dw ?: Reserves a 16-bit word for the result. The quotient ends up in AL (low byte) and the remainder in AH (high byte), so storing all of AX intoccaptures both.
2. Code Segment
mov ax, 0000h: Clears the entire AX register. This is critical — AH must be 0 before loading AL, otherwise the 16-bit dividend in AX will be wrong.mov al, a: Loads the dividend (28h) into AL. AX is now 0028h.div b: Divides AX (0028h = 40 decimal) by the byte in memory variableb(02h). Quotient → AL = 14h (20 decimal), Remainder → AH = 00h.mov c, ax: Stores AX intoc. AL holds the quotient (14h), AH holds the remainder (00h).
Flowchart

Overall Process
- Initialize registers and set up the data segment.
- Clear AX, then load the dividend into AL (AX = 0028h).
- Execute
DIV b: AX ÷ b → AL (quotient), AH (remainder). - Store AX into result variable
cand terminate.
Output
C:TASM>masm an8div.asm
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
Object filename [an8div.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:
50402 + 450254 Bytes symbol space free
0 Warning Errors
0 Severe Errors
C:TASM>link an8div.obj
Microsoft (R) Overlay Linker Version 3.60
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.
Run File [AN8DIV.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
LINK : warning L4021: no stack segment
C:TASM>debug an8div.exe
-g
AX=0014 BX=0002 CX=002A DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B97 ES=0B87 SS=0B97 CS=0B98 IP=0019 NV UP EI PL NZ NA PO NC
0B98:0019 CC INT 3
-d 0B97:0000
0B97:0000 28 02 14 00 00 00 00 00-00 00 00 00 00 00 00 00 (.............
-q
Understanding the Memory Dump
| Memory Address | Value (Hex) | Decimal | Explanation |
|---|---|---|---|
| 0B97:0000 | 28 | 40 | Dividend a = 28h |
| 0B97:0001 | 02 | 2 | Divisor b = 02h |
| 0B97:0002 | 14 | 20 | Quotient in AL — result of 40 ÷ 2 |
| 0B97:0003 | 00 | 0 | Remainder in AH — zero, exact division |
Version 2 — emu8086 (Windows Emulator)
Tested with: emu8086 v4.08 on Windows 10.
; emu8086 version -- 8086 Assembly Program for Division of Two 8-bit Numbers
#make_COM#
org 100h
; --- Code ---
start:
xor ax, ax ; Clear AX (AH must be 0 before 8-bit DIV)
mov al, a ; Load dividend into AL (AX = 0028h)
div b ; AX / b -> AL = quotient (14h), AH = remainder (00h)
mov c, ax ; Store both quotient and remainder
mov ax, 4c00h
int 21h
; --- Data (after code to avoid execution as instructions) ---
a db 28h
b db 02h
c dw 0000h
Version 3 — NASM (Modern Open-Source Assembler)
Tested with: NASM 2.16.01, DOSBox 0.74-3.
; NASM version -- 8086 Assembly Program for Division of Two 8-bit Numbers
; nasm -f bin an8div.asm -o an8div.com
bits 16
org 100h
start:
xor ax, ax ; Clear AX (AH = 0 is mandatory before 8-bit DIV)
mov al, [a] ; Load dividend into AL (AX = 0028h)
div byte [b] ; AX / b -> AL = quotient (14h), AH = remainder (00h)
mov [res], ax ; Store result into variable res
mov ax, 4c00h
int 21h
; --- Data (after code to avoid execution as instructions) ---
a db 28h
b db 02h
res dw 0
Register State After Execution
| Register | Value | Meaning |
|---|---|---|
| AL | 14 | Quotient: 28h ÷ 02h = 14h (20 decimal) |
| AH | 00 | Remainder: 40 ÷ 2 is exact, no remainder |
| AX | 0014 | AH:AL combined — quotient in low byte |
Frequently Asked Questions
What exactly does 8-bit DIV divide?
When the operand of DIV is an 8-bit register or memory byte, the 8086 divides the full 16-bit value in AX by that byte. The quotient lands in AL and the remainder in AH. This is not the same as dividing AL by BL — AX is the dividend, not just AL.
How do I read back the remainder after the division?
After DIV b, AH contains the remainder. In this program mov c, ax stores the entire AX into the 16-bit variable c — so the low byte of c holds the quotient and the high byte holds the remainder. If you want them separately, store AL and AH into two different byte variables.
What is the maximum quotient for 8-bit division?
The quotient must fit in AL (0 to FFh = 0 to 255). If the quotient exceeds FFh — for example dividing AX=0300h by 02h gives a quotient of 180h which does not fit in AL — the CPU raises a Divide Overflow exception (INT 0) and the program crashes. Always ensure the quotient will be within 8-bit range before calling 8-bit DIV.
Conclusion
8-bit division on the 8086 divides the full 16-bit AX by an 8-bit operand, placing the quotient in AL and the remainder in AH. The most important habit is clearing AH before loading AL with the dividend — a dirty AH means a wrong dividend and a wrong result. The cleanest one-instruction way to do this is xor ax, ax before mov al, a.
hii
Is data and ds both same?
hi bidu
thanks
division code in emulator plzzzzzzzzzzzzzzz
Thanks for the program.
..