COA Tutorial
Basic CO and Design
Computer Instructions
Digital Logic Circuits
Map Simplification
Combinational Circuits
Flip - Flops
Digital Components
Register Transfer
Micro-Operations
Memory Organization
COA_Misc
- Booth's Multiplication Algorithm
- Branch Instruction in Computer Organization
- Data Representation in Computer Organization
- ALU and Data Path in Computer Organization
- External memory in Computer Organization
- Structured Computer Organization
- Types of Register in Computer Organization
- Secondary Storage Devices in Computer Organization
- Types of Operands in Computer Organization
- Serial Communication in Computer organization
- Addressing Sequencing in Computer Organization
- Simplified Instructional Computer (SIC)
- Arithmetic Instructions in AVR microcontroller
- Conventional Computing VS Quantum Computing
- Instruction set used in Simplified Instructional Computer
- Branch Instruction in AVR microcontroller
- Conditional Branch instruction in AVR Microcontroller
- Data transfer instruction in AVR microcontroller
- Difference between Memory-based and Register-based addressing modes
- Difference between 1's complement Representation and 2's complement Representation
- CALL Instructions and Stack in AVR Microcontroller
- Difference between Call and Jump Instructions
- Overflow in Arithmetic Addition in Binary number System
- Horizontal Micro-programmed Vs. Vertical Micro-programmed Control Unit
- Hardwired Vs. Micro-programmed Control Unit
- Non-Restoring Division Algorithm for Unsigned Integer
- Restoring Division Algorithm for Unsigned Integer
- Debugging a Machine-level Program
- Dependencies and Data Hazard in pipeline in Computer Organization
- Execution, Stages and Throughput in Pipeline
- Types of Pipeline Delay and Stalling
- Timing Diagram of MOV Instruction
- Advantages and Disadvantages of Flash Memory
- Importance/Need of negative feedback in amplifiers
- Anti-Aliasing - Computer Graphics
- Bus Arbitration in Computer Organization
- Convert a number from Base 2 (Binary) to Base 6
- Cache Coherence
- EHCI
- Cache Memory and Virtual Memory
- Electrical Potential and Potential Difference
- RAM and Cache
- SIM and RIM instructions in 8085 processor
- Clusters in Computer Organization
- Data Types and Addressing Modes of 80386/80386DX Microprocessor
CALL Instructions and Stack in AVR Microcontroller
CALL can be described in the form of a control transfer instruction. With the help of CALL instruction, we are able to call a particular subroutine. A block of instructions is contained by the subroutine. These types of instructions will be frequently executed with the help of subroutine. Because of this subroutine feature, the program will become more structured, and it will also save a lot of memory space. The AVR (Alf and Vegard's RISC processor) microcontroller contains the four types of instruction to call a subroutine, i.e., CALL (call subroutine), RCALL (relative call subroutine), ICALL (indirect call to Z), and EICALL (extended indirect call to Z).
CALL Instruction
The CALL instruction is 4-byte. The opcode is represented with the help of 10 bits, and the address of a target subroutine is represented with the help of 22 bits, just like the JMP instruction. For the AVR, it provides the 4M address space of 000000-$3FFFFF. It has the ability to call subroutine at the provided range of address.
After the execution of subroutine, it is not compulsory that AVR know the address where to come back. So the address of the instruction is saved by the microcontroller on the STACK, which exists just below the CALL instruction. When the execution of a subroutine is completed, the control will be transferred back to the caller with the help of RET instruction. Hence, at the end of a subroutine, the RET instruction must be placed every subroutine.
4.4M
368
Hello Java Program for Beginners
STACK
STACK is a type of frequently used area of memory, which is used to temporarily store the information of a register. When we call the subroutine, it will return the address. It is a part of RAM (Random access memory) of CPU (Central processing unit). There are a few registers that's why the CPU always requires this storage space. When we call a function, the value will be stored in this temporary storage (Stack). With the help of a scratch register, we cannot store the values because they can be changed by the function.
There is also a stack pointer (SP) register that can be used to access the stack. We can implement the stack pointer (SP) in the I/O memory space with the help of two registers, i.e., SPH (high byte of stack pointer), SPL (low byte of stack pointer). Stack works on LIFO (last in first out) method. That means the retrieved last value will be popped out first from the stack. When something is pushed into the stack, that stack will grow up into the higher address. When something is popped from the stack, it will decrease.
There will be two 8 bit register if AVRs (Alf and Vegard's RISC processor) contains more than 256 bytes. The stack pointer will be made of SPL only if AVR contains the memory with less than 256 bytes because the register with 8 bit is able to address only 256 bytes of memory. There is also a PUSH operation, which is used to store the information of CPU on the stack. There is also a POP operation, which is used to load the contents of a stack back into the CPU. These PUSH and POP operations are the most common and simplest way to use the stack. Now we will describe the Push and Pop operations separately.
Pushing onto the STACK
Pushing can be referred to as "placing something at the top of stack". In the beginning, SP has the ability to point to the top of the stack. It basically stores the 64-bit register or a constant onto the stack. The registers "rax" or "r8" are known as the 64-bit register, and "eax" or "r8d" are known as the 32-bit register. When we try to push or add the data onto the stack, it will always save at the place where a stack pointer is pointing. After that, the stack pointer will be decremented by 1.
For example: In the below example, we will use a PUSH instruction to push a register into a stack. The command to do this is described as follows:
- PUSH Rr;
- Rr is specified as any general-purpose register from R0 to R31.
Popping from the STACK
Popping can be referred to as "taking the top thing from the stack". The function of popping is totally opposite to the function of pushing. Here, the content of a stack is popped from the stack and put back into the register. When we try to pop out the data from the stack, the top location of a stack is copied back to register, and the stack pointer is incremented by 1. When the POP is called, the SP is automatically incremented by 1. The POP operation uses the LIFO (Last in first out) method. That means the retrieved last value will be popped out first from the stack.
For example: In this example, we are going to use a POP instruction to pop the content of a stack and put it into the register. The command to do this is described as follows:
- POP Rr;
- Rr is specified as any general-purpose register from R0 to R31.
The content of a register will not be erased when we push a register onto the stack. In this case, the data will be simply placed or copied into the SRAM. When we pop a value from the stack, the content which exits on that address will not be erased by the stack.
Example of PUSH and POP operation:
In this example, we are going to load 30 into rax and then 45 into rex. The command to do this is described as follows:
- PUSH 30
- PUSH 45
- POP rax
- POP rcx
- ret
After executing the first push, the stack is going to have only a single value that is
- 30
After executing the second push, the stack is going to have two values that are
- 30, 45
After executing the first POP, it will first pick up the value 45 and place it in the register rax. After that, the stack will have only one value that is
- 17
After executing the second POP, it will pick up the value 17 and place it in the register rcx. After that, it will leave the stack clean. The last instruction, "ret" will not work perfectly if the stack is not clean. In this case, all the other instructions will work fine except the "ret". This instruction will jump onto the top of the stack no matter what data the stack contains on the top.
Note: If the number of items that we pushed and the number of items that we popped are not the same, our program will be crashed. So we should be careful with our pushes and pops.
When we try to push more than one resister into the stack, we should call the POP instruction in reverse order so that the values of their original registers will be restored, which is described as follows:
- Push r0
- Push r1
- Push r2
- Pop r2
- Pop r1
- Pop r0
As we can see that the above first, second, and third Push instructions store the content of r0, r1, and r3 respectively into the stack. In the Pop operation, the first Pop operation is performed on the r2 because it is entered in the last, and Pop operation is based on the LIFO operation. That's why we first Pop r2, and then r1 and r0.
If we mistakenly call the POP instruction in the wrong order, in this case, the value will be restored into the wrong registers. So we should be careful while calling the POP, which is described as follows:
- ldi r20, 0x01 It is used to load r20 with 0x01
- ldi r21, 0x02 It is used to load r21 with 0x02
- Push r20 It is used to save r20 to the stack
- Push r21 It is used to save r21 to the stack
- Pop r20 It is used to restore r20 (result = 0x02)
- Pop 21 It is used to restore r21 (result = 0x01)
As we can see that the calling of Pop instructions are not performed in the reverse order of what Push was called in. That's why the data of r20 and r21 are swapped in the result. But this feature will be great if we want to swap the two register's content without using the third register.
Note: Registers must be pooped out from the stack in a reverse order that they were pushed so that they can restore their original values.
Stack Pointer
The stack pointer can be defined as a special register in the input/output memory, which is used to point the space that is allocated in SRAM. SP contains the 16-bit register, which also has the SPL and SPH. The SPH will not be required if the microcontroller contains a very small amount of SRAM. In this case, only SPL will be used. From the end of SRAM, the stack normally starts. When we store the data in a stack, it will grow from higher address values to lower address values. The top of the stack is always pointed with the help of a stack pointer.
Initializing Stack pointers
There are different amounts of RAM (random access memory) for the different AVRs. The address of the last RAM location can be specified with the help of RAMEND in the AVR assembler. So RAMEND can be loaded into the SP if we need to initialize the stack pointer to point to the last memory location. As we have learned above that, the stack pointer contains two registers that are SPH (high byte of stack pointer), SPL (low byte of stack pointer). So the high byte of RAMEND will be loaded into the SPH, and low byte of RAMEND will be loaded into the SPL.
As we learn above that, the SP is in input/output memory. So we can use the out instruction to load the value into it. For the new AVRs, the last value of SRAM will be initialized with the help of stack point on power-up. For the older AVRs, it must be manually set up at the time of the beginning of any program. The example of this is described as follows:
- ldi r16, LOW (RAMEND) With the help of this instruction, the low byte of RAMEND will be loaded into r16 register.
- out SPL, r16 With the help of this instruction, the register r16 will be stored into
- the stack pointer low
- ldi r16, High (RAMEND) With the help of this instruction, the high byte of RAMEND will be loaded into r16 register.
- out SPH, r16 With the help of this instruction, the register r16 will be stored into
- the stack pointer high
The include file is used to contain the constant RAMEND in the form of a last address in SRAM. A lot of microcontrollers contain the 16-bit address, which is divided into two 8-bit components with LOW function and HIGH function. These two functions will be loaded into a working register. The constant RAMEND can be less than 16 bits for some small microcontrollers. SPH will not be used in this case, and we will initialize only the SPL register.
- ldi r16, RAMEND It is used to load RAMEND into r16
- out SPL, r16 It is used to store r16 into the stack pointer
Note: Although, the SP is automatically initialized to the RAMEND on power-up with the help of a newer microcontroller. If we have the practice to initialize the stack pointer at the beginning of any program, it will be very good for us. In case of software reset, this practice will be very useful because it will protect the SP from beginning from some other location that is wrong.
CALL instruction, RET instruction, and role of stack
At the time of execution of a CALL instruction, the address of instructions that are below the CALL instruction will be pushed onto the stack. The instructions, which are below the CALL instruction, will be loaded into the PC and will be executed when the subroutine execution is completed, and RET instruction is executed.