Skip to content

Instantly share code, notes, and snippets.

@jay-tux
Created April 25, 2022 15:07
Show Gist options
  • Save jay-tux/89e9c6806d82ed439d2c257f86979090 to your computer and use it in GitHub Desktop.
Save jay-tux/89e9c6806d82ed439d2c257f86979090 to your computer and use it in GitHub Desktop.
Stack information using %esp and %ebp in C++
#include <iostream>
unsigned int stack_zero;
unsigned int stack_last;
#define GETREG(reg, out) \
asm("movl %%" #reg ", %0"\
: "=r" (out)\
: \
)
#define LOGESP() \
unsigned int __esp__; \
unsigned int __ebp__; \
GETREG(esp, __esp__); \
GETREG(ebp, __ebp__); \
std::cout << "%esp = " << __esp__ << "; %ebp = " << __ebp__ << std::endl;
void subfun(int amrec) {
LOGESP();
unsigned int stack_old = stack_last;
std::cout << "Stack size: " << ((long)stack_zero - (long)__esp__) << "B " << "(frame size: " << ((long)stack_last - (long)__ebp__) << "B "
<< "[from " << stack_last << " to " << __esp__ << "])" << std::endl << std::endl;
stack_last = __ebp__;
if(amrec <= 0) return;
subfun(amrec - 1);
stack_last = stack_old;
}
template <int M> inline size_t factorial() {
std::cout << "[factorial<" << M << ">]: ";
LOGESP();
if constexpr(M == 0) return 0;
else if constexpr(M == 1) return 1;
else return M * factorial<M - 1>();
}
int main() {
LOGESP();
stack_zero = __ebp__;
stack_last = __ebp__;
std::cout << "+---" << std::endl
<< "| Calling subfun(3)" << std::endl
<< "+---" << std::endl;
subfun(3);
stack_last = __ebp__;
std::cout << "+---" << std::endl
<< "| Calling subfun(7)" << std::endl
<< "+---" << std::endl;
subfun(7);
std::cout << "+---" << std::endl
<< "| Calling factorial<6>()" << std::endl
<< "+---" << std::endl;
std::cout << factorial<6>() << std::endl;
}
@jay-tux
Copy link
Author

jay-tux commented Apr 25, 2022

Output with -O3 (g++)

%esp = 1189375464; %ebp = 1577812096
+---
| Calling subfun(3)
+---
%esp = 1189375400; %ebp = 1189375400
Stack size: 388436696B (frame size: 388436696B [from 1577812096 to 1189375400])

%esp = 1189375320; %ebp = 1189375320
Stack size: 388436776B (frame size: 80B [from 1189375400 to 1189375320])

%esp = 1189375240; %ebp = 1189375240
Stack size: 388436856B (frame size: 80B [from 1189375320 to 1189375240])

%esp = 1189375160; %ebp = 1189375160
Stack size: 388436936B (frame size: 80B [from 1189375240 to 1189375160])

+---
| Calling subfun(7)
+---
%esp = 1189375400; %ebp = 1189375400
Stack size: 388436696B (frame size: 388436696B [from 1577812096 to 1189375400])

%esp = 1189375320; %ebp = 1189375320
Stack size: 388436776B (frame size: 80B [from 1189375400 to 1189375320])

%esp = 1189375240; %ebp = 1189375240
Stack size: 388436856B (frame size: 80B [from 1189375320 to 1189375240])

%esp = 1189375160; %ebp = 1189375160
Stack size: 388436936B (frame size: 80B [from 1189375240 to 1189375160])

%esp = 1189375080; %ebp = 1189375080
Stack size: 388437016B (frame size: 80B [from 1189375160 to 1189375080])

%esp = 1189375000; %ebp = 1189375000
Stack size: 388437096B (frame size: 80B [from 1189375080 to 1189375000])

%esp = 1189374920; %ebp = 1189374920
Stack size: 388437176B (frame size: 80B [from 1189375000 to 1189374920])

%esp = 1189374840; %ebp = 1189374840
Stack size: 388437256B (frame size: 80B [from 1189374920 to 1189374840])

+---
| Calling factorial<6>()
+---
[factorial<6>]: %esp = 1189375400; %ebp = 1577812096
[factorial<5>]: %esp = 1189375376; %ebp = 1577812096
[factorial<4>]: %esp = 1189375376; %ebp = 1577812096
[factorial<3>]: %esp = 1189375376; %ebp = 1577812096
[factorial<2>]: %esp = 1189375376; %ebp = 1577812096
[factorial<1>]: %esp = 1189375376; %ebp = 1577812096
720

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment