0% found this document useful (0 votes)
15 views

Module 3-1 microprocessor

The document provides an overview of instruction formats and various instructions supported by the 8086 microprocessor, including data transfer, string manipulation, and loop instructions. It explains the process of writing assembly language programs, assembler directives, and the differences between jump and loop instructions. Additionally, it covers the concepts of macros, near and far procedures, and the distinctions between re-entrant and recursive procedures.

Uploaded by

yaishnave devi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views

Module 3-1 microprocessor

The document provides an overview of instruction formats and various instructions supported by the 8086 microprocessor, including data transfer, string manipulation, and loop instructions. It explains the process of writing assembly language programs, assembler directives, and the differences between jump and loop instructions. Additionally, it covers the concepts of macros, near and far procedures, and the distinctions between re-entrant and recursive procedures.

Uploaded by

yaishnave devi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

Module 3

Instruction Formats of 8086

The 8086 microprocessor supports a variety of instruction formats to accommodate different types
of operations and addressing modes. The primary formats are:

1. One-byte Instruction:

o These instructions are simple and require only one byte.

o Example: INC AX increments the AX register.

2. Register-to-Register:

o Instructions that operate between two registers.

o Example: MOV AX, BX moves the contents of BX to AX.

3. Register/Memory to/from Register:

o Instructions that involve transferring data between a register and a memory location
or another register.

o Example: MOV AX, [1234H] moves the content from memory location 1234H to AX.

4. Immediate to Register/Memory:

o Instructions where a constant value (immediate data) is moved to a register or


memory location.

o Example: MOV AX, 1234H loads the immediate value 1234H into AX.

5. Direct Addressing:

o Instructions that specify a memory address directly.

o Example: MOV AX, [1234H] moves the content from memory location 1234H to AX.

6. Register to Segment Register:

o Instructions that involve segment registers.

o Example: MOV DS, AX moves the content of AX to the DS segment register.

2. Instructions with Suitable Example

(i) LEA (Load Effective Address):

• Used to load the address of a variable into a register.

• Example: LEA AX, [BX+SI] loads the effective address formed by BX + SI into AX.

(ii) MOV (Move Data):

• Transfers data from one location to another.

• Example: MOV AX, BX moves the content of BX to AX.

(iii) ADD (Add):


• Adds the source operand to the destination operand and stores the result in the destination.

• Example: ADD AX, BX adds the contents of BX to AX.

(iv) INC (Increment):

• Increments the operand by one.

• Example: INC AX increments the AX register by 1.

(v) CMP (Compare):

• Compares two operands and sets the flags based on the result.

• Example: CMP AX, BX compares the contents of AX with BX.

(vi) XCHG (Exchange):

• Exchanges the contents of two operands.

• Example: XCHG AX, BX exchanges the contents of AX and BX.

3. Data Transfer Instructions in 8086 Microprocessor

Data transfer instructions are used to move data between registers, memory, and I/O ports. Some
key data transfer instructions are:

• MOV: Moves data from source to destination.

o Example: MOV AX, BX (moves data from BX to AX).

• PUSH: Pushes a word onto the stack.

o Example: PUSH AX (pushes AX onto the stack).

• POP: Pops a word off the stack.

o Example: POP AX (pops the top of the stack into AX).

• IN: Inputs a byte or word from a port to the accumulator.

o Example: IN AL, DX (inputs a byte from the port specified by DX into AL).

• OUT: Outputs a byte or word from the accumulator to a port.

o Example: OUT DX, AL (outputs a byte from AL to the port specified by DX).

• LEA: Loads the effective address of the operand into the specified register.

o Example: LEA BX, [SI+2] (loads the effective address of SI + 2 into BX).

4. Instructions Used for String Manipulation in 8086 Microprocessor

String manipulation instructions in the 8086 microprocessor allow operations on sequences of bytes
or words. The key categories are:

• MOVS (Move String): Transfers a byte or word from the source string to the destination
string.

o Example: MOVS B (moves a byte from DS to ES).


• LODS (Load String): Loads a byte or word from the source string into the accumulator.

o Example: LODS B (loads a byte from DS into AL).

• STOS (Store String): Stores a byte or word from the accumulator to the destination string.

o Example: STOSB (stores a byte from AL to ES).

• CMPS (Compare String): Compares two strings byte by byte or word by word.

o Example: CMPSB (compares byte at DS with byte at ES).

• SCAS (Scan String): Scans a string for a specified byte or word.

o Example: SCASB (scans ES for a byte in AL).

5. Loop Instructions, Shift and Rotate Instructions, Logical Instructions, and Branch Instructions

Loop Instructions:

• LOOP:

o Example: LOOP label decrements CX and jumps to label if CX is not zero.

• LOOPZ:

o Example: LOOPZ label decrements CX and jumps to label if CX is not zero and ZF is
set.

Shift and Rotate Instructions:

• SHL (Shift Left):

o Example: SHL AX, 1 shifts the bits in AX to the left by 1.

• ROR (Rotate Right):

o Example: ROR AX, 1 rotates the bits in AX to the right by 1.

Logical Instructions:

• AND:

o Example: AND AX, BX performs a bitwise AND between AX and BX.

• XOR:

o Example: XOR AX, BX performs a bitwise XOR between AX and BX.

Branch Instructions:

• JMP (Unconditional Jump):

o Example: JMP label jumps to the specified label.

• JE (Jump if Equal):

o Example: JE label jumps to label if the Zero Flag (ZF) is set.


Process of writing assembly Language program

Writing an assembly language program involves several steps:

1. Problem Analysis:

• Clearly define the problem and the desired output.

• Break down the problem into smaller, manageable steps.

2. Algorithm Development:

• Create a step-by-step procedure to solve the problem.

• This can be represented in flowchart or pseudocode form.

3. Assembly Language Coding:

• Translate the algorithm into assembly language instructions using appropriate mnemonics
and syntax.

• Use comments to explain the code's functionality.

• Consider data structures and memory allocation.

4. Assembler:

• Use an assembler to translate the assembly code into machine code (object code).

• The assembler checks for syntax errors and generates error messages if necessary.

5. Linker:

• Combine the object code with other modules (if any) and libraries to create an executable
file.

• Resolves external references and creates the final program.

6. Debugging:

• Test the program with different input values to identify and correct errors.

• Use debugging tools to step through the code and examine register values, memory
contents, and flags.

Example: Adding two numbers

DATA SEGMENT
NUM1 DW 1234h
NUM2 DW 5678h
RESULT DW ?
DATA ENDS

CODE SEGMENT
ASSUME CS: CODE, DS:DATA

START:
MOV AX, DATA
MOV DS, AX

MOV AX, NUM1


ADD AX, NUM2
MOV RESULT, AX

MOV AH, 4Ch


INT 21h
CODE ENDS
END START

Difference between jump and loop instructions


Jump Instructions
• Unconditionally transfer program control to a specified address.
• No built-in counter or condition checking mechanism.
• Used for implementing conditional branching and unconditional jumps.
Loop Instructions
• Execute a block of code repeatedly a specified number of times.
• Involve a counter that is decremented after each iteration.
• Automatically check the counter value and decide whether to continue or exit the loop.

Example:
To implement a loop that iterates 10 times:
Using Jump:

MOV CX, 10
LOOP_START:
; code to be repeated
DEC CX
JNZ LOOP_START
Using Loop:
MOV CX, 10
LOOP_START:
; code to be repeated
LOOP LOOP_START

Explain following Assembler Directive in 8086

(i) ASSUME:

• Tells the assembler which segment registers to use for different segments.

• Example: ASSUME CS:code, DS:data

(ii) EQU:

• Defines a constant without allocating storage.

• Example: MAX EQU 100 defines MAX as 100.

(iii) DW (Define Word):

• Allocates and initializes memory for word-sized variables.

• Example: num DW 1234H allocates a word and initializes it to 1234H.

(iv) DD (Define Double Word):

• Allocates and initializes memory for double word-sized variables.

• Example: dword DD 12345678H allocates a double word and initializes it to 12345678H.

(v) ENDS:

• Marks the end of a segment.

• Example: data ENDS indicates the end of the data segment.

Various Flags in 8086

1. Carry Flag (CF):

o Set if there is a carry out from the most significant bit during arithmetic operations.

2. Parity Flag (PF):

o Set if the number of set bits in the result is even.

3. Auxiliary Carry Flag (AF):

o Set if there is a carry from the lower nibble to the upper nibble in BCD operations.

4. Zero Flag (ZF):

o Set if the result of an operation is zero.

5. Sign Flag (SF):


o Set if the result of an operation is negative.

6. Overflow Flag (OF):

o Set if there is a signed overflow in arithmetic operations.

7. Direction Flag (DF):

o Determines the direction of string operations. If set, string operations auto-


decrement; otherwise, they auto-increment.

8. Interrupt Flag (IF):

o Controls the handling of interrupts. If set, interrupts are enabled; if clear, interrupts
are disabled.

Explain the Following Directives: SEGMENT, ENDS, ASSUME, ORG, EQU, and END

1. SEGMENT: Defines the beginning of a segment.

o Example: data SEGMENT

2. ENDS: Marks the end of a segment.

o Example: data ENDS

3. ASSUME: Associates a segment register with a segment.

o Example: ASSUME CS:code, DS:data

4. ORG: Sets the origin (starting address) for the code or data.

o Example: ORG 100h

5. EQU: Defines a constant value.

o Example: MAX EQU 10

6. END: Marks the end of the source code file.

o Example: END _start

DAA, DAS, AAA, and AAS Instructions

These instructions are primarily used for adjusting results of arithmetic operations to accommodate
specific data formats, particularly BCD (Binary Coded Decimal) and ASCII.

DAA (Decimal Adjust Accumulator After Addition)

• Used after an addition operation to correct the result in the accumulator if it contains
unpacked BCD digits.
• Adjusts the accumulator content to valid unpacked BCD digits.

• Sets the auxiliary carry flag (AF) if a carry occurs from bit 3 to bit 4 of a digit.

• Sets the carry flag (CF) if a carry occurs from bit 7 of the accumulator.

DAS (Decimal Adjust Accumulator After Subtraction)

• Used after a subtraction operation to correct the result in the accumulator if it contains
unpacked BCD digits.

• Adjusts the accumulator content to valid unpacked BCD digits.

• Clears the auxiliary carry flag (AF) if a borrow occurs from bit 4 of a digit.

• Sets the carry flag (CF) if a borrow occurs from bit 7 of the accumulator.

AAA (ASCII Adjust Accumulator After Addition)

• Used after an addition of two ASCII digits to correct the result in the accumulator.

• Converts the result from binary to unpacked BCD.

• Sets the auxiliary carry flag (AF) if a carry occurs from bit 3 to bit 4.

• Sets the carry flag (CF) if the result is greater than or equal to 16.

AAS (ASCII Adjust Accumulator After Subtraction)

• Used after a subtraction of two ASCII digits to correct the result in the accumulator.

• Converts the result from binary to unpacked BCD.

• Clears the auxiliary carry flag (AF) if a borrow occurs from bit 4.

• Sets the carry flag (CF) if the result is negative.

Macros in 8086
A macro is a user-defined block of assembly language instructions that can be reused multiple times
within a program. It's a way to define a custom instruction or a sequence of instructions that can be
given a name and used later

Features of Macros in 8086

• Code Reusability: Macros promote code reusability, reducing redundancy in the code.

• Modularity: They help in breaking down complex tasks into smaller, manageable units.

• Flexibility: Macros can accept parameters, allowing for customization.

• Efficiency: While not as efficient as procedures in terms of memory usage, macros can be
faster in execution as there's no function call overhead.

• Definition: Macros are defined using the MACRO and ENDM directives.

• Invocation: A macro is called by using its name in the code.

• Expansion: The assembler replaces the macro call with the actual code at assembly time
Defining a Macro

A macro is defined using the MACRO directive, followed by the macro name and
optional parameters. The macro definition ends with the ENDM directive.

SUM MACRO operand1, operand2, result


MOV AX, operand1
ADD AX, operand2
MOV result, AX
ENDM

In this example:
• The macro SUM takes three parameters: operand1, operand2, and result.
• When the macro is invoked, it generates code to add operand1 and operand2, storing
the result in result.

Invoking a Macro

A macro is invoked by simply using its name and providing the necessary arguments.

.data
num1 DW 5
num2 DW 10
sum DW 0

.code
SUM num1, num2, sum

In this example:
• The SUM macro is called with num1, num2, and sum as arguments.
• The assembler replaces the macro call with the actual code defined in the SUM
macro, resulting in the addition of num1 and num2, storing the result in sum.
Difference between Near and Far procedure

The NEAR and FAR procedures in the 8086 microprocessor are distinguished primarily by their
memory segment usage and how they handle procedure calls. Here are the key differences:

NEAR Procedure

1. Segment Location: A NEAR procedure is defined within the same code segment as the calling
instruction, often referred to as an intra-segment procedure.

2. IP Handling: When a NEAR procedure is called, only the Instruction Pointer (IP) is updated.
The old IP value is pushed onto the stack, allowing the program to return to the correct
location after the procedure execution.

3. Stack Usage: NEAR procedures require fewer stack locations since only the IP value is stored.

4. Keyword Usage: The keyword near is used in the procedure definition.


5. Example Syntax: CALL near_procedure_name

6. Return Mechanism: The return from a NEAR procedure involves popping the old IP value
from the stack back into the IP register.

FAR Procedure

1. Segment Location: A FAR procedure is defined in a different code segment than the calling
instruction, known as an inter-segment procedure.

2. CS and IP Handling: When a FAR procedure is called, both the Code Segment (CS) and IP are
updated. The old CS: IP pair is pushed onto the stack, which allows for a return to the correct
segment and instruction.

3. Stack Usage: FAR procedures require more stack locations because both the CS and IP values
need to be stored.

4. Keyword Usage: The keyword far is used in the procedure definition.

5. Example Syntax: CALL far_procedure_name

6. Return Mechanism: The return from a FAR procedure involves popping both the old IP and
CS values from the stack back into their respective registers.

Differentiate Between Re-entrant and Recursive Procedure

Recursive Procedures

A recursive procedure is one that calls itself during its execution. This self-referential behavior allows
the procedure to solve problems by breaking them down into smaller, more manageable
subproblems. Recursive procedures typically have a base case that stops the recursion to prevent
infinite loops. They are particularly useful for tasks involving complex data structures, such as trees
or graphs.

Key Characteristics of Recursive Procedures:

• Self-Calling: The procedure invokes itself.

• Base Case: Must include a termination condition to avoid infinite recursion.

• Stack Usage: Recursive calls consume stack space, which can lead to stack overflow if the
recursion depth is too high.

• Example Use Cases: Commonly used in algorithms like factorial calculation, Fibonacci series,
and tree traversals.

Re-entrant Procedures

A re-entrant procedure, on the other hand, is designed to be interrupted and safely re-entered
without losing its state. This means that if a re-entrant procedure is in the middle of execution and
an interrupt occurs (for instance, due to a hardware interrupt), the procedure can be paused, the
interrupt can be serviced, and then the procedure can resume execution without any issues.

Key Characteristics of Re-entrant Procedures:

• Interruptible: Can be interrupted and safely resumed.


• Stateless: Should not rely on global or static variables to maintain state, as these could be
altered by the interrupt.

• No Self-Modification: The procedure should not modify its own code during execution.

• Example Use Cases: Frequently used in real-time systems and applications where interrupts
are common, such as embedded systems and multi-threaded environments

Procedure and CALL/RETURN Instructions in 8086

Procedure

A procedure in 8086 assembly language is a block of code that performs a specific task. It's a
modular programming construct that promotes code reusability and organization. Procedures
are similar to functions or subroutines in higher-level programming languages.

Defining a Procedure: To define a procedure, we use the PROC and ENDP directives:

PROCEDURE_NAME PROC NEAR

; Procedure code here

PROCEDURE_NAME ENDP

CALL Instruction

The CALL instruction is used to transfer control from the main program to a procedure. When a
CALL instruction is executed, the following steps occur:

1. The address of the next instruction (return address) is pushed onto the stack.

2. The program counter (IP) is loaded with the address of the first instruction of the procedure.

Syntax:

CALL procedure_name

RETURN Instruction

The RET instruction is used to return control from a procedure back to the calling program. When
a RET instruction is executed, the return address is popped from the stack and loaded into the
program counter.
Syntax:

RET

Reentrant Procedure and Parameter Passing


Reentrant Procedure

A reentrant procedure is a subroutine that can be interrupted during execution and safely re-
entered without producing incorrect results. This is crucial in scenarios involving interrupts,
multi-tasking, or recursion.

Key characteristics of a reentrant procedure:

• No modification of global variables: Any changes to data should be made locally to avoid
conflicts with other instances of the procedure.

• Use of local variables: Data specific to each procedure invocation should be stored in local
variables on the stack.

• Avoid static data: Static data can be shared across multiple invocations, leading to potential
conflicts.

Parameter Passing to Reentrant Procedures

To ensure reentrancy, parameters should be passed to a procedure in a way that doesn't modify
the caller's data. Here are the common methods:

1. Pass by value:

o A copy of the parameter is passed to the procedure.

o Modifications to the parameter within the procedure do not affect the original value.

2. Pass by reference:

o The address of the parameter is passed to the procedure.

o The procedure can modify the original data, but this can lead to potential issues if
not handled carefully.

3. Pass by register:

o Parameters are passed through registers.

o This method is efficient but has limitations on the number of parameters that can be
passed.

Example:
; Pass by value
PROCEDURE PROC NEAR
PUSH BP
MOV BP, SP
MOV AX, [BP+4] ; Access first parameter
; ... procedure code ...
POP BP
RET 2
PROCEDURE ENDP
n the above example, the first parameter is accessed using [BP+4], which is a local variable on the
stack. This ensures that modifications to the parameter within the procedure do not affect the
original value.

Interrupt Vector Table and its Application

The Interrupt Vector Table (IVT) is a table that holds the addresses of the interrupt service routines
(ISRs) for various interrupts. It is located at the beginning of the memory (usually starting at address
0000:0000).

Applications:

• Interrupt Handling: Directs the CPU to the appropriate ISR when an interrupt occurs.

• Device Management: Manages hardware interrupts from devices like keyboards, mice, and
network cards.

• System Calls: Supports operating system services through software interrupts

Compare Procedure and Macro

An assembly program is typically divided into three main sections, each serving a distinct purpose in
the program's structure. These sections are:

1. Data Section

The data section is used for declaring initialized data or constants. This section contains variables
that hold fixed values that do not change during the execution of the program. For example, it can
include constant values, file names, or buffer sizes.

Syntax Example:
section .data

2. BSS Section

The BSS (Block Started by Symbol) section is used for declaring variables that are uninitialized. This
section reserves space in memory for variables that will be initialized at runtime but do not have a
specific value assigned at the time of declaration.

Syntax Example:

section .bss

3. Text Section

The text section contains the actual executable code of the program. This section must begin with a
declaration indicating the entry point of the program, typically using global _start or global main,
which tells the assembler where execution begins

Syntax Example:

section .text

global _start

_start:

Example:

DATA SEGMENT

MESSAGE DB 'Hello, World!', '$'

DATA ENDS

BSS SEGMENT

UNINITIALIZED_VAR DW ?

BSS ENDS

CODE SEGMENT

; executable code here

CODE ENDS

END START

Role of TEST Instruction in Assembly Language Programming

The TEST instruction performs a bitwise AND operation between two operands and sets the flags
accordingly, without modifying the operands. It is typically used for:
• Checking Specific Bits: To test if certain bits are set or cleared.

• Conditionals: Used in conditional branching based on the result of the AND operation.

TEST AX, 1 ; Test if the least significant bit of AX is


set

JZ even ; If zero flag is set, AX is even

JNZ odd ; If zero flag is not set, AX is odd

Function of Assembler Directives

Assembler directives are commands that give instructions to the assembler on how to process the
assembly language code. They do not generate machine code themselves but influence the assembly
process:

• Data Definition: Directives like DB, DW, and DD are used to define data types and initialize
variables.

• Segment Definition: Directives like SEGMENT, ENDS, and ASSUME are used to define code,
data, and stack segments.

• Constants: Directives like EQU define constants.

• Macros: Directives like MACRO and ENDM define and manage macros for code reuse.

• Assembly Control: Directives like ORG and END control the assembly process, specifying the
origin address and the end of the source code.

Compare similarities and difference between PUSH/POP and CALL/RET instructions.

The PUSH/POP and CALL/RET instructions in assembly language have some similarities and
differences:

Similarities

• Both PUSH/POP and CALL/RET instructions use the stack to store and retrieve data.

• PUSH and CALL instructions decrement the stack pointer by 2 (for 16-bit processors) to make
space for the data being pushed onto the stack.

• POP and RET instructions increment the stack pointer by 2 to remove the data from the top
of the stack.

Differences

• PUSH/POP instructions are used to store and retrieve data on the stack,
while CALL/RET instructions are used for subroutine calls and returns.

• PUSH stores the contents of a register or memory location on the stack, while CALL stores
the current value of the program counter (return address) on the stack before jumping to the
subroutine.
• POP retrieves data from the stack and stores it in a register or memory location,
while RET retrieves the return address from the stack and jumps back to the calling program.

• PUSH/POP instructions do not affect any flags, while CALL/RET instructions do not affect
flags directly.

Stack and Subroutine in 8086

Stack

A stack is a Last-In-First-Out (LIFO) data structure used for temporary storage of data during program
execution. In the 8086 microprocessor, the stack is a region of memory accessed using the Stack
Segment (SS) and Stack Pointer (SP) registers.

• SS register: Specifies the starting address of the stack segment.

• SP register: Points to the top of the stack.

The stack grows downwards in memory, meaning data is pushed onto the stack by decrementing the
SP register, and popped off by incrementing the SP register.

Basic Stack Operations:

• PUSH: Pushes a word-sized value onto the stack.

• POP: Pops a word-sized value from the stack.

Subroutine

A subroutine is a block of code that performs a specific task and can be called from different parts of
a program. It promotes modularity and code reusability.

Subroutine and Stack Interaction:

• When a subroutine is called using the CALL instruction, the return address (the address of
the next instruction after the CALL) is pushed onto the stack.

• The program counter is then loaded with the address of the first instruction of the
subroutine.

• The subroutine can use the stack to store local variables and parameters.

• When the subroutine finishes, the RET instruction pops the return address from the stack
and transfers control back to the calling program.
MAIN PROC NEAR
PUSH AX
CALL SUBROUTINE
POP AX
; ...
MAIN ENDP

SUBROUTINE PROC
NEAR
; Subroutine code
RET
SUBROUTINE ENDP

Conditional Call and Return Instructions in 8086

The 8086 microprocessors doesn't have direct conditional call or return instructions. However, you
can achieve similar functionality by combining conditional jump instructions with the regular CALL
and RET instructions.

Conditional Call

To implement a conditional call, you can use a conditional jump instruction to check a specific
condition, and if the condition is met, execute a CALL instruction to transfer control to the desired
procedure.

Example:

CMP AX, BX ; Compare AX and BX


JB LESS_THAN ; Jump to LESS_THAN if AX is less than
BX
; Continue execution if AX is not less than BX
LESS_THAN PROC NEAR
; Code for when AX is less than BX
RET
LESS_THAN ENDP

Conditional Return

Similarly, a conditional return can be achieved by using a conditional jump to a location immediately
after the RET instruction if the desired condition is not met.

Example:
MY_PROCEDURE PROC NEAR

; Procedure code

CMP RESULT, 0

JGE POSITIVE_RETURN ; Jump if result is greater than or equal to zero

; Code for negative result

POSITIVE_RETURN:

RET

MY_PROCEDURE ENDP

The Stack in 8086

The 8086 microprocessor uses a stack for temporary data storage. The stack is a Last-In-First-Out
(LIFO) data structure, meaning the last item pushed onto the stack is the first item popped off.

Key components:

• Stack Segment (SS) register: Specifies the starting address of the stack segment in memory.

• Stack Pointer (SP) register: Points to the top of the stack.

PUSH Operation

The PUSH instruction pushes a word-sized value onto the stack.

Steps involved:

1. The SP register is decremented by 2 to make space for the word to be pushed.

2. The value to be pushed is stored at the memory location pointed to by SS:SP.

Syntax:

PUSH source

source can be a register, memory location, or immediate value.

POP Operation

The POP instruction pops a word-sized value from the stack and stores it in the specified destination.

Steps involved:

1. The value at the memory location pointed to by SS:SP is copied to the destination.

2. The SP register is incremented by 2 to point to the new top of the stack.

Syntax:

POP destination

destination can be a register or memory location.


Example

PUSH AX

PUSH BX

POP CX

POP DX

In this example, the values in registers AX and BX are pushed onto the stack. Then, the values are
popped off the stack and stored in registers CX and DX, respectively.

Recursive Procedures

A recursive procedure is one that calls itself during its execution. This self-referential behaviour
allows the procedure to solve problems by breaking them down into smaller, more manageable
subproblems. Recursive procedures typically have a base case that stops the recursion to prevent
infinite loops. They are particularly useful for tasks involving complex data structures, such as trees
or graphs.

Key Characteristics of Recursive Procedures:

• Self-Calling: The procedure invokes itself.

• Base Case: Must include a termination condition to avoid infinite recursion.

• Stack Usage: Recursive calls consume stack space, which can lead to stack overflow if the
recursion depth is too high.

• Example Use Cases: Commonly used in algorithms like factorial calculation, Fibonacci series,
and tree traversals.

Example: Factorial Calculation

FACTORIAL PROC NEAR


CMP AX, 1
JLE FACTORIAL_END
PUSH AX
DEC AX
CALL FACTORIAL
POP BX
MUL BX
FACTORIAL_END:
RET
FACTORIAL ENDP

In this example:
• The base case is when AX is less than or equal to 1.

• The recursive case involves calling the FACTORIAL procedure again with AX decremented.

• The result is calculated by multiplying the current AX value with the result of the recursive
call.

Macro for 32-bit by 16-bit Division of Unsigned Numbers in Assembly Language

• We need to divide a 32-bit unsigned number by a 16-bit unsigned number.


• The 8086 DIV instruction can only handle a 32-bit dividend divided by a 16-bit divisor.
• The result (quotient) will be in AX and the remainder in DX.

DIV32_16 MACRO DIVIDEND_HI, DIVIDEND_LO, DIVISOR


; Assuming DIVIDEND_HI and DIVIDEND_LO contain the 32-bit dividend
; and DIVISOR contains the 16-bit divisor

MOV DX, DIVIDEND_HI ; Move the upper 16 bits of the dividend to DX


MOV AX, DIVIDEND_LO ; Move the lower 16 bits of the dividend to AX
DIV DIVISOR ; Divide the 32-bit dividend by the 16-bit divisor

; The quotient is now in AX and the remainder is in DX


ENDM

Here,

• The macro DIV32_16 takes three parameters: DIVIDEND_HI, DIVIDEND_LO for the 32-bit
dividend (upper and lower 16 bits) and DIVISOR for the 16-bit divisor.
• The MOV instructions load the upper 16 bits of the dividend into DX and the lower 16 bits
into AX.
• The DIV instruction performs the 32-bit by 16-bit division.
• The quotient is stored in AX and the remainder in DX.

Example:
DATA SEGMENT
NUM32_HI DW 0FFFFh
NUM32_LO DW 0ABCDh
DIVISOR DW 01234h
QUOTIENT DW ?
REMAINDER DW ?
DATA ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA

START:
MOV AX, DATA
MOV DS, AX

DIV32_16 NUM32_HI, NUM32_LO, DIVISOR

MOV QUOTIENT, AX
MOV REMAINDER, DX

; ...
CODE ENDS
END START

You might also like