|
In this webpage, I want to show you the effect of these sequence of instructions and their effect on the program stack with 3 examples
main( )
{
Calls a function A and passes 2 parameters to A.
In Java, this would be written as: A(1111,2222)
}
A( int a, int b )
{
A( ) has 3 local variables.
In Java, you would write:
int x, y, z; // Define 3 local vars
return(9999); // A( ) always returns 9999
}
|
I will only show you how the parameters and local variables are stored in the program stack
The assembler code is as follows:
main:
mov r0, #2222 // Pass 2222 as parameter 2 on stack
push {r0}
mov r0, #1111 // Pass 1111 as parameter 1 on stack
push {r0}
bl A // Call function A
add sp, sp, #8 // Clean up parameters on the stack
// When A returns, you will see the return value in r0 = 9999
nop
nop
Stop:
nop
/* ==============================================
Function A: param and locals in stack
============================================== */
A:
// When run in EGTAPI - you will see {1111, 2222} on stack
/* ****************************************
Prelude: build stack frame
**************************************** */
push {lr} // Save return address in LR
push {fp} // Save Frame Pointer in FP
mov fp, sp // Initialize my own FP
sub sp, sp, #12 // I create 3 local variable in stack
nop // These instructions in A( ) can use stack
nop // to access parameters and local variables
/* ====================================================
We can use a register to return the return value
==================================================== */
mov r0, #9999 // Pass return value in register r0
/* ************************************************
Postlude: break down stack frame
************************************************ */
mov sp, fp // De-allocate the local variables
pop {fp} // Restore old FP
pop {pc} // Return
|
I will show this example in class and also highlight the effect of the instructions
What you should notice is:
|
How to run the program:
|
main( )
{
A(1111,2222)
}
A( int a, int b )
{
int x, y, z; // Define 3 local vars
B(3333,4444,5555);
return(9999);
}
B( int a, int b, int c )
{
int x, y; // Define 2 local vars
return(8888);
}
|
I will only show you how the parameters and local variables are stored in the program stack
The assembler code is as follows:
main:
mov r0, #2222 // Pass 2222 as parameter 2 on stack
push {r0}
mov r0, #1111 // Pass 1111 as parameter 1 on stack
push {r0}
bl A // Call function A
add sp, sp, #8 // Clean up parameters on the stack
// When A returns, you will see the return value in r0 = 9999
nop
nop
Stop:
nop
/* ==============================================
Function A: param and locals in stack
============================================== */
A:
// When run in EGTAPI - you will see {1111, 2222} on stack
/* ****************************************
Prelude: build stack frame
**************************************** */
push {lr} // Save return address in LR
push {fp} // Save Frame Pointer in FP
mov fp, sp // Initialize my own FP
sub sp, sp, #12 // I create 3 local variable in stack
nop // These instructions in A( ) can use stack
nop // to access parameters and local variables
/* =========================================
Call B( ) with 3 parameters
========================================= */
mov r0, #5555 // Pass 5555 as parameter 3 on stack
push {r0}
mov r0, #4444 // Pass 4444 as parameter 2 on stack
push {r0}
mov r0, #3333 // Pass 3333 as parameter 1 on stack
push {r0}
bl B // Call function B
add sp, sp, #12 // Clean up parameters on the stack
nop // We are back in A( )
nop // We will now return to main( )
/* ====================================================
We can use a register to return the return value
==================================================== */
mov r0, #9999 // Pass return value in register r0
/* ************************************************
Postlude: break down stack frame
************************************************ */
mov sp, fp // De-allocate the local variables
pop {fp} // Restore old FP
pop {pc} // Return
|
I will show this example in class and also highlight the effect of the instructions
What you should notice is:
|
How to run the program:
|
|
Then you can easily understand that you access the parameters and local variables with these offsets:
|
localVar1 = param1;
localVar2 = param2;
localVar3 = param1 + param2;
|
Example:
main:
mov r0, #2222 // Pass 2222 as parameter 2 on stack
push {r0}
mov r0, #1111 // Pass 1111 as parameter 1 on stack
push {r0}
bl A // Call function A
add sp, sp, #8 // Clean up parameters on the stack
// When A returns, you will see the return value in r0 = 9999
nop
nop
Stop:
nop
A:
// When run in EGTAPI - you will see {1111, 2222} on stack
/* ****************************************
Prelude: build stack frame
**************************************** */
push {lr} // Save return address in LR
push {fp} // Save Frame Pointer in FP
mov fp, sp // Initialize my own FP
sub sp, sp, #12 // I create 3 local variable in stack
// How to to access parameters and local variables
// stored in the program stack
ldr r0, [fp, #8] // Get parameter 1 = 1111
str r0, [fp, #-12] // Store in local variable 1
ldr r1, [fp, #12] // Get parameter 2 = 2222
str r1, [fp, #-8] // Store in local variable 2
add r0, r0, r1
str r0, [fp, #-4] // Store sum in local variable 3
/* =================================================
We can use a register to return the return value
================================================= */
mov r0, #9999 // Pass return value in register r0
/* ************************************************
Postlude: break down stack frame
************************************************ */
mov sp, fp
pop {fp}
pop {pc} // Return
|
How to run the program:
|