FB stack internals

Jump to: navigation, search

(This stuff is mostly just of interest to TMC, who has trouble remembering all of it)

Documentation of the details of FreeBASIC stack usage, upon which the OHR's GOSUB implementation and the original unofficial FB 0.22 Mac OS X port depend. If it changes in a future version of FB, we are in trouble. It's also not expected to work when using -gen gcc (however, FB's GOSUB implementation using setjmp/longjmp technically should not work either:

"If you use longjmp, beware of automatic variables. ISO C says that automatic variables that are not declared volatile have undefined values after a longjmp. And this is all GCC promises to do, because it is very difficult to restore register variables correctly, and one of GCC's features is that it can put variables in registers without your asking it to." [1]


ebp addressed part of the stack
esp addressed part of the stack (normally via push/pop)
cdecl function calls on FB 0.22 Mac OS X only

Content Notes
Arguments [ebp+8] and above
Stack frame 'header' eip
Function-scope local variables Starts at [ebp-4]. First local is function return value
Temporaries Scoped locals, intermediate results, WITH pointer, FOR start/end/step Fixed length, variable contents
Saved registers from previous function Any of the following used:
GOSUB call pointers call gosub_FUNC_line_LINE Variable length
Nested function call arguments (Recent FB versions only). Arguments pushed from right to left Variable length
Topmost function call Padding to 16 byte boundary garbage 0 - 12 bytes
Saved stack pointer esp
Arguments Variable length

FB never pushs partially evaluated function arguments to the stack as a typical C compiler would, instead preferring to store the arguments in the preserved registers (ebx, esi, edi), and then overflowing to temporary variables. Along with eax for a returned result, it normally doesn't need to use temporaries until a single function requires at least 5 returned values as arguments.

The preceding statement is false; presumably it became false sometime between FB 0.22 when I originally investigated, and FB 1.0.