function with no locals still gets local storage created

13 views
Skip to first unread message

Gordon Joel

unread,
Nov 9, 2014, 3:43:56 PM11/9/14
to asmji...@googlegroups.com
It seems that X86Compiler (Win32) generates 8-bytes of local storage regardless of whether a function uses local variables. If you log the very first example from the README (code with logging below), you get this:
Logger Content:
L0:
sub esp, 8                          ;
mov eax, [esp+12]                   ; [Alloc] a
mov ecx, [esp+16]                   ; [Alloc] b
add eax, ecx                        ; add a, b xR
L1:
add esp, 8                          ;
ret                                 ;

So my question is: what is the purpose of the sub esp, 8 ?

#include <asmjit/asmjit.h>


using namespace asmjit;
int main(int argc, char* argv[]) {
 
// Create JitRuntime and X86 Compiler.
 
JitRuntime runtime;
  X86Compiler c
(&runtime);




 
StringLogger logger;
  c
.setLogger(&logger);


 
// Build function having two arguments and a return value of type 'int'.
 
// First type in function builder describes the return value. kFuncConvHost
 
// tells compiler to use a host calling convention.
  c
.addFunc(kFuncConvHost, FuncBuilder2<int, int, int>());


 
// Create 32-bit variables (virtual registers) and assign some names to
 
// them. Using names is purely optional and only greatly helps while
 
// debugging.
  X86GpVar a
(c, kVarTypeInt32, "a");
  X86GpVar b
(c, kVarTypeInt32, "b");


 
// Tell asmjit to use these variables as function arguments.
  c
.setArg(0, a);
  c
.setArg(1, b);


 
// a = a + b;
  c
.add(a, b);


 
// Tell asmjit to return 'a'.
  c
.ret(a);


 
// Finalize the current function.
  c
.endFunc();


 
// Now the Compiler contains the whole function, but the code is not yet
 
// generated. To tell compiler to generate the function make() has to be
 
// called.


 
// Make uses the JitRuntime passed to Compiler constructor to allocate a
 
// buffer for the function and make it executable.
 
void* funcPtr = c.make();


 
// In order to run 'funcPtr' it has to be casted to the desired type.
 
// Typedef is a recommended and safe way to create a function-type.
 
typedef int (*FuncType)(int, int);


 
// Using asmjit_cast is purely optional, it's basically a C-style cast
 
// that tries to make it visible that a function-type is returned.
 
FuncType func = asmjit_cast<FuncType>(funcPtr);


 
// Finally, run it and do something with the result...
 
int x = func(1, 2);
  printf
("x=%d\n", x); // Outputs "x=3".




  printf
("Logger Content:\n%s", logger.getString());




 
// The function will remain in memory after Compiler is destroyed, but
 
// will be destroyed together with Runtime. This is just simple example
 
// where we can just destroy both at the end of the scope and that's it.
 
// However, it's a good practice to clean-up resources after they are
 
// not needed and using runtime.release() is the preferred way to free
 
// a function added to JitRuntime.
  runtime
.release((void*)func);


 
// Runtime and Compiler will be destroyed at the end of the scope.
 
return 0;
}

Petr Kobalíček

unread,
Nov 10, 2014, 4:52:59 PM11/10/14
to asmjit-dev
Hi Gordon,

I will check this out. It's definitely a bug, but fortunately it doesn't cause any damage. It's not really high priority, but I can track this down and fix.

Best
Petr

--

---
You received this message because you are subscribed to the Google Groups "asmjit-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to asmjit-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages