CPU-Memory Connection Explained
CPU-Memory Connection Explained
The connection between the processor (CPU) and the memory in a computer is a vital part of computer architecture. These components work together through a structured
system of buses and control units to enable data flow and processing. Here's a breakdown of the connection:
Components Involved:
1. Processor (CPU):
o Contains subcomponents such as the Arithmetic and Logic Unit (ALU), Control Unit (CU), and Registers.
2. Memory:
o Primary Memory (RAM): Temporary, high-speed storage for data and instructions.
o Cache Memory: Small, fast memory located near or inside the processor for frequently accessed data.
o Secondary Memory: Permanent storage (e.g., HDD, SSD) connected indirectly via the memory hierarchy.
3. System Bus:
The result is stored in MDR, and the address is sent to MAR for writing back to memory.
Here's a simplified list of steps needed to execute the machine instruction "Add LOCA, R0," using the transfer between components as described:
1. Transfer PC to MAR: Copy the contents of the Program Counter (PC) to the Memory Address Register (MAR).
2. Read from memory: Issue a Read command to memory and wait for the word to be transferred into the Memory Data Register (MDR).
3. Load instruction into IR: Transfer the instruction from MDR into the Instruction Register (IR) and decode it.
4. Transfer address LOCA to MAR: Transfer the address LOCA from IR to MAR.
5. Read operand from memory: Issue a Read command and wait until MDR is loaded with the value from LOCA.
6. Transfer operand from MDR to ALU: Transfer the contents of MDR to the Arithmetic Logic Unit (ALU).
8. ALU operation: The ALU performs the addition of the two operands (LOCA and R0) and transfers the result back into R0.
10. Increment PC: Add 1 to the operand in the ALU and transfer the incremented address back to PC.
Connection Workflow:
1. Fetching Instructions:
o The Program Counter (PC) in the CPU holds the address of the next instruction.
o The Address Bus transfers this address to the Memory Address Register (MAR).
o A read signal is sent via the Control Bus to fetch the instruction from memory.
o The instruction is fetched into the Memory Data Register (MDR) and transferred to the Instruction Register (IR).
2. Fetching Data:
o If the instruction requires data (operands), the CPU sends a memory address (via the MAR and Address Bus).
o Memory responds by placing the data on the Data Bus.
3. Processing Data:
o The ALU processes the data as per the instruction in the IR.
4. Storing Results:
A write signal is sent via the Control Bus to store the data in memory.
o To improve speed, frequently used data is stored in cache memory, which is much closer to the CPU.
2. Clock Synchronization:
o CPU and memory operations are synchronized using a clock signal to ensure smooth data flow.
3. Hierarchy:
o A memory hierarchy (cache → RAM → secondary storage) ensures an efficient balance of speed, size, and cost.
Block Diagram:
System Bus (Data Bus, Address Bus, Control Bus) connecting the CPU and Memory.
Instruction sequencing is the process of executing a sequence of machine instructions in a specific order to accomplish a desired computational task. Instructions are categorized
based on their functionality and the number of operands they work with.
Instructions are the commands given to a processor to perform specific operations, such as arithmetic, data transfer, or control. The basic types of instructions include:
1. Arithmetic Instructions:
o Transfer data between memory and registers, e.g., Load, Store, Move.
3. Control Instructions:
4. Logic Instructions:
Instructions in a processor are used to perform various operations such as arithmetic computations, data transfer, and control flow management. Here's a breakdown of the basic
instruction types with examples:
1. Arithmetic Instructions:
These instructions perform mathematical operations like addition, subtraction, multiplication, and division.
Examples:
ADD R1, R2: Adds the value in register R2 to the value in register R1 and stores the result in R1.
MUL R1, R2: Multiplies the values in R1 and R2, storing the result in R1.
DIV R5, R6: Divides the value in R5 by the value in R6, storing the quotient in R5 and remainder in R6.
These instructions are used to move data between memory and registers, or between different registers.
Examples:
LOAD R1, 1000: Loads the value from memory address 1000 into register R1.
STORE R1, 2000: Stores the value in register R1 into memory location 2000.
MOVE R2, R3: Copies the value in register R3 into register R2.
3. Control Instructions:
Control instructions manage the sequence of execution in a program, such as branching or calling subroutines.
Examples:
JUMP 5000: Jumps to memory address 5000 and starts executing from there.
BRANCH ZERO, 2000: Jumps to memory location 2000 if the zero flag is set.
CALL 4000: Calls the subroutine starting at address 4000 and stores the return address.
4. Logic Instructions:
These instructions perform logical operations on binary values, such as AND, OR, and NOT.
Examples:
AND R1, R2: Performs a bitwise AND on the values in R1 and R2, storing the result in R1.
OR R3, R4: Performs a bitwise OR on the values in R3 and R4, storing the result in R3.
Examples:
o SHL (Shift Left): Shifts the bits of a value to the left, filling with zeroes or sign extension.
SHL R1, 1: Shifts the value in R1 left by 1 bit, and stores the result back in R1.
SHR R2, 2: Shifts the value in R2 right by 2 bits, and stores the result in R2.
Summary:
Data Transfer Instructions: Move data between memory and registers or between registers.
Logic Instructions: Perform logical operations like AND, OR, and NOT.
Shift and Rotate Instructions: Modify data at the bit level by shifting or rotating.
Example of Instruction Sequencing:
C=A+B
1. Fetch Operands:
o The contents of memory locations A and B are fetched into the processor.
2. Compute Result:
o The sum of the values of A and B is computed inside the Arithmetic Logic Unit (ALU).
3. Store Result:
Add A, B, C
Operands:
o C: Destination operand.
Operation:
Instruction Format:
Contains the memory addresses of three operands: Source1, Source2, and Destination.
Steps in Execution:
1. Fetch Operands:
o The processor retrieves the contents of memory locations A and B and loads them into temporary registers (e.g., R1 and R2).
Three-Address Instructions
Format: ADD A, B, C
Explanation: The instruction ADD A, B, C performs the operation [A] + [B] and stores the result in [C].
o Operands:
Challenge: Each operand (A, B, C) needs a memory address, which requires multiple bits for encoding, leading to a larger instruction size. This can exceed the word size
of the processor, requiring multi-word instructions.
2. Two-Address Instructions
Format: ADD A, B
Explanation: The instruction ADD A, B adds the contents of memory location A to the contents of B. Here, B serves as both a source and a destination.
Challenge: Though more compact than three-address instructions, this approach still requires multiple instructions.
3. One-Address Instructions
Format: ADD A
Explanation: One-address instructions use an accumulator (a special register) for operations. For example, ADD A adds the contents of memory location A to the
contents of the accumulator.
Challenge: While the instruction format is compact, the use of the accumulator for all operations can limit flexibility and performance in certain tasks.
Format: ADD
Explanation: In a zero-address instruction set (typically used in stack-based architectures), operations are implicitly performed on values at the top of the stack. For
example, ADD would pop two values from the stack, add them, and push the result back onto the stack.
ADD — pops A and B, adds them, and pushes the result back.
Operands or Addresses: The locations or values involved in the operation (e.g., A, B, C).
Different instruction formats provide various trade-offs between simplicity, flexibility, and performance.
Three-Address: ADD A, B, C
This sequence of instructions illustrates how different architectures can handle the same high-level operation in different ways.
Branching in instruction sequencing allows a program to execute a specific set of instructions repeatedly or conditionally, based on certain conditions. Here’s a breakdown of
how branching works, particularly in the context of creating loops.
2. Register Usage:
o R1: Used as a counter to keep track of how many numbers need to be added.
o R0: Holds the cumulative sum of the numbers as they are added.
o Program Counter (PC): Holds the address of the next instruction to be executed.
setup:
1. Store the number of entries in the list: The number of entries, n, is stored at memory location N.
2. Load the counter into R1: The value of N (the number of numbers to sum) is loaded into R1.
Loop Execution:
4. Determine Address:
o The next number from the list is fetched and added to the running total in R0.
6. Decrement Counter:
7. Branch Instruction:
o A conditional Branch > 0 is used to check if R1 is still greater than 0 (i.e., if more numbers need to be added).
o If R1 is still greater than 0, the program branches to the LOOP address and continues with the next iteration.
End of Loop:
8. Store Result:
o After all numbers are added, the total in R0 is moved to the SUM location in memory.
.
Conditional Branch:
The Branch > 0 instruction checks if the value in R1 is greater than 0. If true, the program jumps back to LOOP to continue the addition.
Summary of Instructions:
3. R0 = R0 + Next Number: Fetch the next number from memory and add it to R0.
6. Move R0, SUM: When the loop ends, store the result in SUM.
o Instead of writing a long sequence of instructions (like multiple ADD instructions), you can place a single ADD instruction in a loop, which will be repeated as
necessary.
o The loop is a sequence of instructions executed multiple times depending on the condition.
o The number of times the loop should be executed is stored in memory location N.
o Register R1 is used as a counter to determine the number of times the loop is executed.
o At the beginning of the program, the value of N (the number of iterations) is loaded into register R1.
o Once R1 becomes 0, the loop will stop, and the program will proceed with the next instruction.
4. Conditional Branching:
o Branch instructions change the normal flow of execution by loading a new address into the program counter (PC).
o This new address is called the branch target. When the branch occurs, the processor will fetch and execute the instruction at the new address, instead of
continuing with the next sequential instruction.
o A conditional branch occurs only if a specified condition is met (e.g., Branch > 0).
For example: Branch > 0 LOOP causes a branch to the LOOP label if the value in R1 is greater than 0.
If the condition is not met, the program will continue executing sequentially.
1. Initial Setup: Load the value of N (number of iterations) into register R1.
2. Loop Execution:
Decrement R1 by 1.
If R1 is greater than 0, the program will branch back to LOOP and repeat the process.
3. End of Loop:
Once R1 reaches 0, the loop ends, and the program proceeds to the next instruction.
The result stored in R0 is then moved to memory location SUM (final result).
2. LOOP: ADD [memory], R0 — Fetch the next entry from memory and add it to R0.
3. DECREMENT R1 — Decrement the counter register (R1).
4. BRANCH R1 > 0, LOOP — If R1 is still greater than 0, go back to the LOOP label.
5. MOVE R0, SUM — Once the loop ends, store the result from R0 into the memory location SUM.
In computer architecture, condition codes (or status flags) are special bits within a processor that store information about the results of various operations. These flags play a
crucial role in controlling the flow of execution, particularly for conditional branch instructions, which depend on specific conditions being met after operations like addition,
subtraction, etc.
Let's break down the details and usage of condition codes step by step:
Condition codes are bits used by the processor to record the outcomes of operations.
These flags provide information on whether the result of an operation (arithmetic, logic, or data transfer) meets specific criteria, such as being negative, zero, or causing
overflow.
The processor maintains a special register, typically called the Condition Code Register (CCR) or Status Register, where these flags are stored.
There are typically four important flags that are most commonly used:
1. N (Negative Flag)
Behavior:
o Cleared to 0 if the result is not negative (i.e., it’s either positive or zero).
2. Z (Zero Flag)
Behavior:
3. V (Overflow Flag)
Behavior:
o Set to 1 if an overflow happens. This happens when the result of an operation exceeds the maximum value that can be represented by the given number of bits
(e.g., adding two large numbers that causes the result to go beyond the processor’s word size).
4. C (Carry Flag)
Purpose: The C flag indicates whether there was a carry-out from the most significant bit during an operation.
Behavior:
o Set to 1 if a carry-out occurs during an arithmetic operation (e.g., during addition or subtraction).
A conditional branch instruction checks the state of the condition code flags (N, Z, V, C) and, based on their values, determines whether to jump to a different part of the
program. The most common condition flags include:
N (Negative Flag): Set to 1 if the result of the last operation was negative.
C (Carry Flag): Set to 1 if there was a carry during an operation (used for operations on larger numbers).
From your input, I assume you have an example involving some bit values and status flags. You may want to evaluate a sequence of conditions and determine what happens with
the program's flow based on the flag states.
C = 1: This means the Carry flag is set, indicating a carry-out occurred during an operation.
N = 0: This means the Negative flag is not set, so the result of the last operation was non-negative (either zero or positive).
V = 0: This means there was no overflow in the last operation. The result was within the allowable range of values for the operands.
Z = 0: This means the Zero flag is not set, so the result of the operation was non-zero.
Overflow occurs during an arithmetic operation when the result exceeds the range of values that can be represented using the available number of bits.
Example:
o If you add two positive numbers and the result exceeds +127, overflow occurs.
o Similarly, if you add two negative numbers and the result is less than -128, overflow occurs.
V = 0: No overflow occurred.
Key Points:
If operands have the same sign (both positive or both negative) and the result has a different sign, overflow occurs.
The Carry flag is used in unsigned arithmetic to indicate when a carry-out occurs from the most significant bit during an addition operation.
Example:
o If you add 200 + 100 = 300, the result cannot fit in 8 bits. The carry-out is generated from the most significant bit.
C = 1: Carry occurred (the result does not fit in the word size).
C = 0: No carry occurred.
Key Points:
It is crucial for performing multi-word arithmetic (e.g., adding 64-bit numbers on a 32-bit processor).
Condition codes (status flags) provide information about the result of the last operation performed. These flags are stored in the Condition Code Register (CCR) or Status
Register (SR).
Common Flags:
1. N (Negative Flag):
o Cleared to 0 otherwise.
2. Z (Zero Flag):
o Cleared to 0 otherwise.
3. V (Overflow Flag):
o Cleared to 0 otherwise.
4. C (Carry Flag):
o Cleared to 0 otherwise.
Branch instructions are used to alter the normal sequential flow of a program based on the condition flags.
Key Concepts:
A conditional branch instruction tests one or more condition flags and branches (jumps) to a new instruction if the condition is met.
If the condition is not met, the program continues executing the next sequential instruction.
Example: Branch>0
This instruction causes a branch if:
o N = 0 (not negative).
o Z = 0 (not zero).
1. Operands:
2. Operation:
o A + B = 130.
3. Binary Addition:
-------------
4. Flags:
5. Branching Instruction:
No branch because Z = 0.
Summary
Condition Flags: Help guide conditional branching instructions like Branch>0, Branch Negative, and Branch if Zero.
Conditional Branching allows dynamic control of program flow based on the results of operations.
Addressing modes define how the location of an operand is specified in an instruction. They offer different ways to access memory locations or registers for performing
operations. Here's a detailed explanation of the various addressing modes:
1. Register Mode
Description: In this mode, the operand is stored in a register, and the instruction specifies the register.
Example:
Effective Address (EA): The address is directly the register being referenced (e.g., EA = Ri).
Description: The operand is located at a specific memory address, and the address is explicitly provided in the instruction.
Example:
Move LOC, R0 ; Load the contents of the memory location LOC into register R0
Effective Address (EA): The address is the specified location (e.g., EA = LOC).
3. Immediate Mode
Description: The operand is explicitly specified in the instruction itself as a constant value.
Example:
Effective Address (EA): The value is directly given in the instruction and does not refer to memory (e.g., EA = Immediate Value).
4. Indirect Mode
Description: The operand is accessed through a memory location or register that contains the address of the operand.
Subtypes:
o Memory Indirect: The memory location contains the address of the operand.
Move R1, (R2) ; Fetch data from the address contained in R2 and store it in R1
Effective Address (EA): The address is the contents of the register (e.g., EA = [Ri]).
Move (LOC), R0 ; Fetch the data at memory address LOC and load it into R0
Effective Address (EA): The address is the content of the memory location at LOC (e.g., EA = [LOC]).
5. Indexing Mode
Description: The effective address of the operand is calculated by adding a constant value (offset) to the value in a register. This is particularly useful for accessing
elements in an array or list.
Example:
Effective Address (EA): EA = X + [Ri], where X is the offset and Ri is the register.
8. Relative Mode
Description: The effective address is calculated relative to the current value of the program counter (PC), commonly used for branch instructions.
Example:
Branch >0 LOOP ; If condition is met, jump to location LOOP relative to the current PC
9. Auto-Increment Mode
Description: The register value is used to fetch the operand, and after the operand is accessed, the register is automatically incremented to point to the next item in
memory.
Example:
Effective Address (EA): EA = [Ri], and after the operand is accessed, Ri is incremented.
10. Auto-Decrement Mode
Description: The register value is decremented before being used to access the operand. This is typically used when accessing data in reverse order.
Example:
Addressing modes specify how the operand of an instruction is located. Here’s a summary of the key addressing modes discussed:
o Example: Move LOC, R0 (Load the value at memory location LOC into R0).
3. Immediate Mode
o Example: MOV #200, R0 (Load the immediate value 200 into R0).
4. Indirect Mode
Example: Move R1, (R2) (Fetch the value at the address in R2 and store it in R1).
Example: Move (LOC), R0 (The content at LOC points to the actual memory address, which is used to load data into R0).
5. Index Mode
o The effective address is the sum of a base register's content and a constant value (offset).
o A combination of two registers (one holding the base and the other holding the offset) to compute the effective address.
o Example: Add (R1, R2) (The operand is at the address computed by adding the contents of R1 and R2).
o Example: Add X(R1, R2) (The address is calculated by adding contents of R1, R2, and the offset X).
8. Relative Mode
o The effective address is determined by the current value of the program counter (PC) plus an offset.
o Example: Branch >0 LOOP (Branch to the LOOP location if the condition is met).
9. Auto-increment Mode
o The operand is accessed via a register, and after accessing the operand, the register is incremented.
o Example: (R2)+, R0 (The address in R2 is used to fetch data, and then R2 is incremented to point to the next address).
The operand is accessed via a register, and before accessing the operand, the register is decremented.
Example: (R2)-, R0 (Decrement R2 and then access the operand at the new address).
Effective Address (EA): Not applicable, as the data is directly in the register.
Example:
Move R1, R2
Description: The operand is located in a specific memory location explicitly mentioned in the instruction.
Example:
Move LOC, R2
o If LOC = 1000:
EA = 1000.
3. Immediate Mode
Effective Address (EA): Not applicable, as the operand is part of the instruction itself.
Example:
Move #200, R0
4. Indirect Mode
Description: The address of the operand (Effective Address) is stored in a pointer (register or memory location).
Effective Address (EA): The value in the pointer register or memory location.
Example:
Add (R1), R0
5. Index Mode
Description: The effective address is calculated by adding an offset (displacement) to the value in the index register.
Example:
Add 20(R1), R2
EA = 1000 + 20 = 1020.
Example:
Description: Adds an offset to the sum of two registers to calculate the effective address.
8. Relative Mode
Description: Calculates the effective address relative to the program counter (PC).
Example:
EA = 3000 + 50 = 3050.
Description: Uses the current value of a register as the effective address and then increments the register.
Example:
Add (R1)+, R2
o If R1 = 1000:
EA = 1000.
Description: Decrements the value in a register first, and then uses the new value as the effective address.
Example:
Add -(R1), R2
o If R1 = 1000:
EA = 999.
Stack
A stack is a data structure that organizes elements in a way that allows data to be added and removed only from one end, which is called the top. The other end of the stack
is called the bottom.
Stacks follow the Last In, First Out (LIFO) principle, which means that the last element added (pushed) to the stack is the first one removed (popped).
You can only add plates to the top of the stack (push).
When you want to serve a plate, you take the one on top first (pop).
If plates are added in the order: Plate1, Plate2, Plate3 — Plate3 will be removed first (because it was added last).
Push:
The Stack Pointer (SP) is used to keep track of the current top of the stack.
Pop:
This operation removes the item from the top of the stack.
After the item is removed, the SP is updated to point to the new top of the stack.
The stack is stored in memory, and the Stack Pointer (SP) is a special register that holds the address of the current top item in the stack.
When an item is pushed, the SP is decremented (because stacks typically grow downwards in memory).
In byte-addressable memory, with a 32-bit word length, the operations can be implemented in assembly as follows:
Push Operation
Subtract #4, SP // Decrement the stack pointer by 4 (since each word is 4 bytes)
Move NEWITEM, (SP) // Store NEWITEM at the current top of the stack (address in SP)
This first decrements the stack pointer by 4 and then stores the new item at the new top of the stack.
Pop Operation
Move (SP), ITEM // Retrieve the item from the current top of the stack (address in SP)
Add #4, SP // Increment the stack pointer by 4 (moving to the next item in the stack)
This retrieves the item at the top and then updates the stack pointer to the next item.
Some processors have Autoincrement and Autodecrement addressing modes, which simplify the push and pop operations.
Move NEWITEM, -(SP) // Store NEWITEM at the address pointed by SP and decrement SP automatically
Move (SP)+, ITEM // Retrieve the item at the current top and increment SP automatically
These modes help in optimizing the code and reduce the need for explicit increment or decrement instructions.
o Example:
o Overflow:
o Underflow:
A stack frame is a portion of the stack used to store information related to a function or subroutine call, including parameters, local variables, and return addresses. It helps
manage the execution of subroutines and functions in a structured manner. Here’s a breakdown of the stack frame operations:
1. Frame Pointer (FP): Used to access the parameters passed to the subroutine and local variables. It remains fixed during the execution of the subroutine.
2. Stack Pointer (SP): Points to the top of the stack and changes as items are pushed or popped onto/from the stack. Unlike the FP, SP moves during the function's
execution.
Stack Frame Simplified
A stack frame is a part of the stack used to manage a function or subroutine call. It stores:
How It Works
o Push the parameters and the return address onto the stack.
2. Setting Up:
o Set the frame pointer (FP) to the current top of the stack (SP).
o Use the stack to store local variables and registers (if needed).
Example:
Key Points
SP: Points to the top of the stack and changes during execution.
o Used to access function parameters and local variables in a stable manner, even as the stack pointer changes.
o Moves up (decrements) or down (increments) as items are pushed or popped from the stack.
The return address (the location to resume execution after the function completes) is pushed onto the stack.
The new frame pointer (FP) is initialized to the current value of the stack pointer (SP).
Instruction: Move SP, FP
Space for the function’s local variables is reserved by adjusting the stack pointer (SP).
Example: Subtract #12, SP → Reserves 12 bytes for 3 local variables (4 bytes each).
4. Saving Registers (Optional):
If the function needs to use processor registers (e.g., R0, R1), their values are saved onto the stack to avoid overwriting them.
Instruction: Push R0 or Push R1.
Restoring Registers: If any registers were saved, their original values are restored.
Instruction: Pop R1, Pop R0
Deallocating Local Variables: Space allocated for local variables is freed by adjusting SP.
Example: Add #12, SP → Frees 12 bytes of local variables.
Instruction: RET → Jumps back to the return address, transferring control to the calling function.
o Initially, the stack pointer (SP) is pointing to the old top of the stack (oldTOS).
o The CALL instruction is executed, pushing the return address (address to resume after function execution) onto the stack.
o Once the subroutine begins execution, the Frame Pointer (FP) is initialized by saving the old value of FP and setting FP to the current value of SP.
o Move FP, -(SP) → Saves the old FP value onto the stack.
o Move SP, FP → Initializes FP with the current value of SP, so both FP and SP now point to the saved FP address.
o Local variables are pushed onto the stack. To allocate space for them, the following instruction is executed:
Subtract #12, SP → Reserves space for 3 local variables (each 4 bytes) in this case.
o If required, processor registers (e.g., R0, R1) are saved onto the stack to preserve their values during the function execution.
o This is done by pushing the register values onto the stack before executing the subroutine's task.
o The subroutine now executes its task with its local variables and parameters accessed through the stack frame.
o When the subroutine finishes its task, it begins the clean-up process:
Restore registers: The saved values of R0 and R1 are popped from the stack and restored to their original registers.
Remove local variables: The space allocated for local variables is deallocated by executing:
Restore old FP: The old value of FP is popped from the stack and restored by:
o The SP now points to the return address (address of the instruction after the CALL), so the Return instruction (RET) is executed.
o The calling program pushes 4 parameters onto the stack (each 4 bytes).
o Push any necessary registers (e.g., R0, R1) onto the stack.
3. Subroutine Task:
o The subroutine performs its task using the parameters and local variables from the stack frame.
o The Return instruction (RET) is executed, transferring control back to the calling program.
SUBROUTINES • “A subtask consisting of a set of instructions which is executed many times is called a Subroutine”.
Definition of Subroutine:
A subroutine is a set of instructions that performs a specific task and can be executed multiple times within a program. It is essentially a "sub-task" of the main program.
A Call instruction transfers control to the subroutine, and a Return instruction brings control back to the point immediately after the subroutine call.
Subroutine Linkage:
The method that allows a program to call and return from subroutines is referred to as subroutine linkage. In the simplest linkage mechanism:
1. The Call instruction stores the address of the next instruction (the return address) into a Link Register.
3. The Return instruction uses the Link Register to return to the address stored there.
1. Call Instruction:
o The Call instruction saves the Program Counter (PC) (which contains the address of the next instruction after the call) into a link-register.
Operations of Call:
2. Return Instruction:
o The Return instruction branches to the address stored in the link-register, returning control to the instruction immediately following the subroutine call.
Operations of Return:
o Branch to Link Register (this is the address of the instruction after the subroutine call).
; Subroutine ADD
ADD:
POP R1 ; Pop first number into R1
POP R2 ; Pop second number into R2
ADD R0, R1, R2 ; R0 = R1 + R2
RET ; Return to calling program
#5 and #10 are passed as parameters via the stack.
The result is returned in R0
3. Passing Parameters by Value and Reference: There are two common methods for passing parameters:
o Pass-by-Value: The actual value of the parameter is passed to the subroutine.
o Pass-by-Reference: Instead of passing the actual data (like a list), the address of the data is passed. This allows the subroutine to modify the original data.
Example:
o Pass-by-Reference: The address of the first element of the list is passed, so the subroutine can access and modify the list directly.
o Pass-by-Value: The actual size of the list (n) is passed, which is used as a value by the subroutine.
; Calling Program
PUSH NUM1 ; Push the address of the first number (pass by reference)
PUSH #5 ; Push the size of the list (pass by value)
CALL LISTADD ; Call the subroutine
; Subroutine LISTADD
LISTADD:
POP R2 ; Pop the address of the first number into R2
POP R1 ; Pop the size of the list into R1
; Perform addition of numbers using R1 and R2
ADD R0, R2, R1 ; Compute the sum and store it in R0
RET ; Return to the calling program
In this example, NUM1 is passed by reference (the address of the first number), while n is passed by value (the number of elements).
Here is a program to evaluate the expression Y=A×B+C×DY = A \times B + C \times DY=A×B+C×D using a single accumulator processor. The processor has the instructions LOAD, STORE,
MULTIPLY, and ADD.
Assume that:
A,B,C,DA, B, C, DA,B,C,D are stored in memory locations.
YYY is the result to be stored.
Program Steps:
1. Load the first operand AAA.
2. Multiply it by BBB.
3. Store the result temporarily.
4. Load the second operand CCC.
5. Multiply it by DDD.
6. Add the result of the second multiplication to the temporary result.
7. Store the final result in YYY.
; Assume A is at memory location 1000
; Assume B is at memory location 1001
; Assume C is at memory location 1002
; Assume D is at memory location 1003
; Y will be stored at memory location 1004