How does one implement alloca() using inline x86 assembler in languages like D, C, and C++? I want to create a slightly modified version of it, but first I need to know how the standard version is implemented. Reading the disassembly from compilers doesn’t help because they perform so many optimizations, and I just want the canonical form.
Edit: I guess the hard part is that I want this to have normal function call syntax, i.e. using a naked function or something, make it look like the normal alloca().
Edit # 2: Ah, what the heck, you can assume that we’re not omitting the frame pointer.
implementing
allocaactually requires compiler assistance. A few people here are saying it’s as easy as:which is unfortunately only half of the picture. Yes that would ‘allocate space on the stack’ but there are a couple of gotchas.
if the compiler had emitted code which references other variables relative to
espinstead ofebp(typical if you compile with no frame pointer). Then those references need to be adjusted. Even with frame pointers, compilers do this sometimes.more importantly, by definition, space allocated with
allocamust be ‘freed’ when the function exits.The big one is point #2. Because you need the compiler to emit code to symmetrically add
<size>toespat every exit point of the function.The most likely case is the compiler offers some intrinsics which allow library writers to ask the compiler for the help needed.
EDIT:
In fact, in glibc (GNU’s implementation of libc). The implementation of
allocais simply this:EDIT:
after thinking about it, the minimum I believe would be required would be for the compiler to always use a frame pointer in any functions which uses
alloca, regardless of optimization settings. This would allow all locals to be referenced throughebpsafely and the frame cleanup would be handled by restoring the frame pointer toesp.EDIT:
So i did some experimenting with things like this:
which unfortunately does not work correctly. After analyzing the assembly output by gcc. It appears that optimizations get in the way. The problem seems to be that since the compiler’s optimizer is entirely unaware of my inline assembly, it has a habit of doing the things in an unexpected order and still referencing things via
esp.Here’s the resultant ASM:
As you can see, it isn’t so simple. Unfortunately, I stand by my original assertion that you need compiler assistance.