Skip to main content

8086

8086 Assembly Program to Compute the Power of a Number Using Exponentiation by Squaring

This blog post details an 8086-assembly program that computes the power of a number using the Exponentiation by Squaring algorithm (O(log n) efficiency). While a standard iterative approach multiplies the base n times (taking O(n) time), exponentiation by squaring—also known as binary exponentiation—works by breaking the exponent down into its binary components. By squaring the base in each step and only multiplying it into the result when a bit in the exponent is set, we drastically reduce the computational load. For example, calculating x32 requires only 5 multiplications instead of 31. This example demonstrates advanced assembly concepts like bitwise manipulation, conditional branching, and efficient arithmetic optimization. Let’s get started! Logic Breakdown: The algorithm follows the mathematical identity of Binary Exponentiation: Check Exponent: If it's zero, stop. Odd Case: If the current exponent is odd, multiply the running result by the current base. Square and Halve: Regardless of odd/even, square the base and divide the exponent by 2. Loop: Continue until the exponent is exhausted. Let's visualize it's working for 53. StepBase ExponentResult ActionInitial531Start loopIter 153 (Odd)51 X 5 = 5Square251552 = 25, 3/2 = 1Iter 2251 (Odd)1255 X 25 = 125Square6250125252 = 625,1/2 = 0Exit-0125Loop terminates

8086 Assembly Program to Compute the Power of a Number

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

8086 Assembly Program for Bitwise Operations: AND, OR, XOR, and NOT

This blog post will walk you through a simple 8086 assembly program designed to perform bitwise operations: AND, OR, XOR and NOT on 8-bit numbers. While these operations have a straightforward purpose, they are foundational when working at low level, manipulating bits, flags and registers. Let’s get started! data segment a db 0Ah ; first 8-bit operand (10 decimal) b db 05h ; second 8-bit operand (5 decimal) res_and db ? ; result of a AND b res_or db ? ; result of a OR b res_xor db ? ; result of a XOR b res_not db ? ; result of NOT a data ends code segment assume cs:code, ds:data start: mov ax, data mov ds, ax ; load operands into registers mov al, a mov bl, b ; AND operation: AL = AL AND BL and al, bl mov res_and, al ; reload operands for next operation mov al, a mov bl, b ; OR operation: AL = AL OR BL or al, bl mov res_or, al ; reload operands for next operation mov al, a mov bl, b ; XOR operation: AL = AL XOR BL xor al, bl mov res_xor, al ; NOT operation on first operand: AL = NOT AL mov al, a not al mov res_not, al int 3 ; breakpoint / stop for debug code ends end start

8086 Assembly Program to Compute the Greatest Common Divisor (GCD) of Two 16-bit Numbers Using Euclidean Algorithm

In this blog post, we’ll explore an 8086 assembly program that computes the Greatest Common Divisor (GCD) of two numbers using the classic Euclidean Algorithm. The Euclidean method is an efficient and elegant way to find the largest number that divides both inputs without leaving a remainder. The principle is simple:GCD(A, B) = GCD(B, A mod B) This process repeats until the remainder becomes zero. At that point, the divisor is the GCD. Let’s dive into the code and understand how it works! Program Code data segment a dw 0012h ; First number (18 decimal) b dw 000Ah ; Second number (10 decimal) gcd_result dw ? ; Variable to store the GCD data ends code segment assume cs:code, ds:data start: mov ax, data mov ds, ax ; Initialize data segment mov ax, a ; Load A into AX mov bx, b ; Load B into BX cmp bx, 0000h ; Check if B is zero jz store_result gcd_loop: mov dx, 0000h ; Clear DX before division div bx ; AX = AX / BX, remainder in DX cmp dx, 0000h ; If remainder = 0, GCD found je store_result_bx mov ax, bx ; A = B mov bx, dx ; B = remainder jmp gcd_loop ; Repeat loop store_result_bx: mov ax, bx ; Move GCD into AX store_result: mov gcd_result, ax ; Store final result int 3 ; Stop execution code ends end start

8086 Assembly Program to Calculate the Factorial of an Integer Using Loops and Registers

In this post, we'll walk through an 8086 assembly program that calculates the factorial of a given integer. This program highlights the power of the 8086's loop instruction and the use of general-purpose registers for iterative calculations. We'll use the AX register as an accumulator for the result and the CX register as a loop counter, which is its special-purpose function. Let's get to the code!

Introduction to Memory Segmentation in 8086

The complete starting point for 8086 study: the processor's 1978 origins, why Intel built it, its headline features, real-world applications, and the memory segmentation mechanism that lets 16-bit registers address a full 1 MB — with the physical address formula, all four segment registers, overlap rules, .COM vs .EXE differences, and the .MODEL directive.

8086 MASM Assembly Program for Addition of Two 8-bit Numbers

This blog post will guide you through a MASM (Microsoft Macro Assembler) program that performs the addition of two 8-bit numbers. While this is a fundamental operation, it demonstrates crucial assembly programming concepts such as data handling, register usage, and memory storage. Let’s dive in! Assembly Code

Understanding INT 3h vs INT 21h in 8086 Assembly

In 8086 assembly programming, interrupts play a crucial role in handling various operations, from debugging to system calls. Two commonly used interrupts are INT 3h (Breakpoint Interrupt) and INT 21h (DOS Interrupt). While both involve interrupt handling, their functionalities and use cases are completely different. In this blog post, we will explore the differences between INT 3h and INT 21h, their respective use cases, and practical examples to understand their behavior. TL;DR INT 3h is used for debugging; it stops execution and hands control to the debugger. INT 21h is used for system services like displaying messages, reading input, and terminating the program. Key Difference: INT 3h is a 1-byte instruction (CC), while INT 21h requires function numbers in AH to specify system calls.

8086 Data Directives: DB, DW, DD, DQ, DT, DUP, EQU, PTR, and OFFSET

Data directives are assembler instructions, not CPU instructions — they tell the assembler how much memory to reserve and what value to store there at load time. The CPU never executes a DB or DW; it simply finds the bytes already in memory when it accesses that address at runtime. Choosing the right directive matters: use DB for bytes and strings, DW for 16-bit integers and addresses, DD for far pointers and 32-bit values, and DUP to initialise arrays without typing each value individually.