I recently learned about Assembly x86 and how functions are implemented in it and how the stack program works.
However, I tried writing this program which calls a function f2 by changing the return address of the current called function f1, so that the instruction pointer starts f2 when finishing f1, therefore not returning directly to main.
It seems unstable and sometimes I get segmentation fault, while in another cases it works but does not return 0.
Why is that?
My guess is that the program stack is not given a contiguous space in memory at run time and so its behavior is not constant.
Sometimes it works if a change v[2] = (uintptr_t) f2;
into v[another_index_greater_than_2] = (uintptr_t) f2;
.
It is odd, since in theory v[1] should be the old base pointer pushed on the stack, while v[2] should be the return address of the function.
#include <iostream>
using namespace std;
int main();
void f2()
{
int v[1];
cout << "f2\n";
v[2] = (uintptr_t) main;
}
void f1()
{
int v[1];
cout << "f1\n";
v[2] = (uintptr_t) f2;
}
int main()
{
f1();
cout << "Back to main";
return 0;
}
I expected to see the 3 strings printed in order (f1, f2, main) and the program to return 0, but the behavior of the program seems to be random.