This blog post details an 8086-assembly program that computes the power of a number, specifically baseexponent. This example demonstrates fundamental assembly concepts like loops, multiplication, and register manipulation to perform iterative arithmetic. Let’s get started!
data segment
base dw 0003h
exponent dw 0004h
result dd ?
data ends
code segment
assume cs:code, ds:data
start:
; Initialize data segment
mov ax, data
mov ds, ax
; Initialize result to 1 (R = B^0)
mov word ptr result, 0001h
mov word ptr result+2, 0000h
; Load base and exponent
mov cx, exponent ; CX = exponent (loop counter)
mov bx, base ; BX = base
cmp cx, 0000h
je exit ; If exponent is 0, result is already 1. Jump to exit.
power_loop:
; Multiply result by base
; The result is a 32-bit number in result[0] (lower word) and result[2] (upper word)
; Multiplication requires careful handling of the 32-bit result with a 16-bit multiplier.
; 1. Multiply the lower word of result by base
mov ax, word ptr result ; AX = result[0]
mul bx ; AX * BX -> DX:AX (32-bit product)
push dx ; Save the higher word (DX) of the product
mov word ptr result, ax ; Store the lower word (AX) of the product as the new result[0]
; 2. Multiply the upper word of result by base
mov ax, word ptr result+2 ; AX = result[2]
mul bx ; AX * BX -> DX:AX (32-bit product)
; 3. Add the two 16-bit 'carry' terms
pop cx ; Retrieve the saved higher word (DX) from step 1 into CX
add ax, cx ; AX = AX + CX (Sum of two high words)
adc dx, 0000h ; DX = DX + 0 + Carry from the previous ADD (final carry from the 32-bit multiplication)
; 4. Store the final upper word
mov word ptr result+2, ax ; Store AX as the new result[2]
; Handle the 32-bit overflow (DX is the final carry from the 32-bit multiplication)
; For a 32-bit result storage, this program assumes the result fits in 32-bits.
; If the power is large, overflow might occur, which is a limitation of this 32-bit storage approach.
loop power_loop ; Decrement CX and jump back to power_loop if CX != 0
exit:
int 3 ; Program termination
code ends
end start
Understanding the Code
This program is more complex than simple multiplication because it involves repeated 16-bit multiplication to compute a potentially 32-bit result, requiring special handling of carries and intermediate products.
Data Segment:
data segment: Defines the variables.base dw 0003h: Declares a 16-bit word variablebase, initialized to 310.exponent dw 0004h: Declares a 16-bit word variableexponent, initialized to 410.result dd ?: Declares a 32-bit doubleword variableresultto store the final product, 34 = 8110 (0051h).
Flowchart:

Code Segment:
assume cs:code, ds:data: Directs the assembler on segment register usage.start:: Program execution entry point.mov ax, data/mov ds, ax: Segment Setup. Makes thedatasegment accessible.mov word ptr result, 0001h/mov word ptr result+2, 0000h: Initialization. Sets the initialresult(32-bit) to 1. (base0 = 1).mov cx, exponent: Loads theexponent(4) into the CX register, which acts as the loop counter for theLOOPinstruction.mov bx, base: Loads thebase(3) into the BX register, the multiplier.cmp cx, 0000h/je exit: Checks if the exponent is 0. If so, the result is 1, and the program exits.power_loop:: The label marking the start of the loop (where multiplication occurs).- 32-bit Multiplication Logic: The core of the program is the multiplication of the 32-bit result by the 16-bit base (in BX). The full calculation is:
- (result[2] X 216 + result[0]) X base
- = (result[2] X base) X 216 + (result[0] X base)
mov ax, word ptr result: Loads the lower word of the 32-bitresultinto AX.mul bx: Multiplies AX X BX. The 32-bit product is stored in DX:AX.push dx: Saves the upper word of this first product (which is a carry into the next 16-bit position) onto the stack.mov word ptr result, ax: Stores the lower word (AX) of the product as the newresult[0].mov ax, word ptr result+2: Loads the upper word of the old 32-bitresultinto AX.mul bx: Multiplies AX X BX. The 32-bit product is again stored in DX:AX. This product is (result[2] X base) X 216.pop cx: Retrieves the saved carry (from result[0] X base) into CX.add ax, cx: Adds the saved carry (in CX) to the current lower 16 bits of the upper product (in AX). This completes the calculation of the new upper word.adc dx, 0000h: Adds DX (the carry from the multiplication in step 2) plus the Carry Flag (CF) set by the previousADD. This final carry (in DX) would be the next higher word (the 5th byte) if we were storing a 48-bit result.mov word ptr result+2, ax: Stores the new upper word (AX) as the newresult[2].
loop power_loop: Decrements CX and jumps back topower_loopif CX != 0.exit:: Label for program termination.int 3: Halts the program.
On High-Level
- Initialization: Variables (
base,exponent) are set, and the 32-bitresultis initialized to 1. - Segment Setup: The data segment is made accessible.
- Loop Setup: The
exponentis loaded into the loop counter (CX). - Loop/Multiplication: A loop executes
exponenttimes:- The current 32-bit
resultis multiplied by the 16-bitbase. - The multiplication is broken into two 16-bit parts, carefully managing the 32-bit product and the intermediate carries.
- The new 32-bit product is stored back into
result.
- The current 32-bit
- Program Termination: Execution is halted.
Output
C:\TASM>masm power.asm
Microsoft (R) Macro Assembler Version 5.00
Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.
Object filename [power.OBJ]:
Source listing [NUL.LST]:
Cross-reference [NUL.CRF]:
50288 + 450368 Bytes symbol space free
0 Warning Errors
0 Severe Errors
C:\TASM>link power.obj
Microsoft (R) Overlay Linker Version 3.60
Copyright (C) Microsoft Corp 1983-1987. All rights reserved.
Run File [POWER.EXE]:
List File [NUL.MAP]:
Libraries [.LIB]:
LINK : warning L4021: no stack segment
C:\TASM>debug power.exe
-g
AX=0051 BX=0003 CX=0000 DX=0000 SP=0000 BP=0000 SI=0000 DI=0000
DS=0B97 ES=0B87 SS=0B97 CS=0B98 IP=002F NV UP EI PL NZ NA PO NC
0B98:002F CC INT 3
-d 0B97:0000
0B97:0000 03 00 04 00 51 00 00 00-B8 97 0B 8E D8 C7 06 04 ....Q...........
0B97:0010 00 01 00 C7 06 06 00 00-00 8B CE 8B DB 83 F9 00 ................
0B97:0020 74 0D A1 04 00 F7 E3 52-A3 04 00 A1 06 00 F7 E3 t......R........
0B97:0030 59 03 C1 13 D2 A3 06 00-E2 EB CC E9 CD FF B8 0A Y...............
0B97:0040 00 50 E8 47 5E 83 C4 04-5E 8B E5 5D C3 90 55 8B .P.G^...^..]..U.
-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 03 00 04 00 51 00 00 00-B8 97 0B 8E D8 C7 06 04 ....Q...........
- The value
03 00(stored as little-endian) representsbase = 0003h. - The value
04 00(stored as little-endian) representsexponent = 0004h. - After the program runs:
- The value
51 00 00 00represents the 32-bitresult. resultholds 00000051h, which is the correct decimal result 34 = 8110 (51h).
- The value