RTUEE / EC / EEEYr 2022 · Sem 52022

Q1Microprocessor

Question

8 marks

Q.1. What is the use of Stack? Explain "PUSH" and "POP" operations with the help of suitable examples.

Answer

A stack is a Last-In-First-Out (LIFO) memory structure used to temporarily save the Program Counter (during CALL/interrupt) and register contents; PUSH copies a register pair's contents onto the stack (decrementing SP), while POP retrieves them back off the stack (incrementing SP), always in reverse order of pushing.

Use of Stack: the stack is a reserved area of RAM organized as a Last-In-First-Out (LIFO) data structure, accessed via the Stack Pointer (SP) register, which always holds the address of the current 'top' of the stack. The stack is used primarily for two purposes: automatically saving the return address (Program Counter) whenever a CALL instruction is executed (so the CALLed subroutine's corresponding RET instruction can later retrieve this address and correctly resume execution at the instruction immediately following the original CALL), and for the programmer to explicitly, temporarily save the contents of registers (using PUSH) before using those same registers for some other purpose within a subroutine, then restore their original values (using POP) before returning, ensuring the calling program's register contents are not disturbed by the subroutine's internal operations.

PUSH operation: the PUSH instruction (e.g., PUSH B, in 8085 syntax, pushing the BC register pair) copies the contents of the specified 16-bit register pair onto the stack, in two steps: first, the Stack Pointer is decremented by 1, and the high-order byte of the register pair is stored at this new SP address; then the Stack Pointer is decremented by 1 again, and the low-order byte of the register pair is stored at this second new SP address. Since SP always decrements before each byte is stored, PUSH effectively 'grows' the stack downward in memory (toward lower addresses) as more data is pushed.

POP operation: the POP instruction (e.g., POP B) reverses this process, retrieving data back off the stack in the opposite order it was pushed: first, the byte at the current SP address is read into the low-order byte of the specified register pair, and SP is incremented by 1; then the byte at the new SP address is read into the high-order byte of the register pair, and SP is incremented by 1 again — restoring the register pair to exactly the value it held at the time of the corresponding PUSH, provided PUSH and POP operations are correctly balanced (every PUSH eventually matched by a corresponding POP) and executed in strict LIFO (last-pushed, first-popped) order.

Example: suppose BC = 1234H and DE = 5678H, and the program executes PUSH B followed by PUSH D, then later POP D followed by POP B. After PUSH B: SP decrements and 12H (high byte of BC) is stored, SP decrements again and 34H (low byte of BC) is stored. After PUSH D: SP decrements and 56H (high byte of DE) is stored, SP decrements again and 78H (low byte of DE) is stored — so the stack now holds (from top/most-recently-pushed to bottom): 78H, 56H, 34H, 12H. Executing POP D first correctly retrieves 78H into E and 56H into D, restoring DE = 5678H (the most recently pushed value, retrieved first — the LIFO property); then executing POP B retrieves 34H into C and 12H into B, restoring BC = 1234H. This example illustrates why PUSH and POP operations must always be used in strictly matched, reverse (LIFO) order — if the program instead attempted POP B before POP D, it would incorrectly retrieve DE's pushed value into the BC register pair, corrupting both registers' intended final values, which is a common and important source of bugs in assembly language programs that use the stack for temporary register preservation across subroutine calls.

Back to Paper