i know this is the big deal to manipulate stack but i think it would be a great lesson for me. im searched the internet, and i found calling convention. I know how its working and why. I whant to simulate some of "Callee clean-up stack" maybe stdcall, fastcall its doesnt matter, important think is that who clean-up stack, then i will be have less work do to :)
for example. i have function in C
double __fastcall Add(int a, int b) {
return a + b;
}
it will be Calee
and i have pointer to this function with type void*,
void* p = reinterpreted_cast<void*>(Add);
And i have function Caller
void Call(void* p, int a, int b) {
//some code about push and pop arg
//some code about save p into register
//some code about move 'p' into CPU to call this function manually
//some code about take of from stack/maybe register the output from function
}
And thats it, its helpful when i use calling convention "Calle clean-up" because i dont need
//some code about cleans-up this mess
I dont know how to do it, i know it can be done with assembler. but i afraid about it, and i never 'touch' this language. i would be greatful to simulate that calling with C, but when anyone can do it with ASM i will be haapy :)
I told also what i whant to do with it, when i will be know how to manually call function, i will be able to call function with several parameters(if i know the number and size of it) and any type of function. so i will be able to call any function in any language when that function is in the right calling convention.
I'm using Windows OS x64 and MinGw
First of all: C is intended to hide calling conventions and everything that is specific to how your code is executed from the programmer and provide an abstract layer above it.
The only condition when you need to (as you say) "manually" call a function is when you do it from
asm
.C as a language has no direct control over the stack or the program counter.
To cite from GCC manual for
fastcall
for x86:Also as far as I remember return values are passed in
EAX
.So in order to call a function in this way you need to provide the arguments in
ECX
,EDX
and then invoke thecall
instruction on the function addressPlease note I have changed the return type to
int
, because I do not remember how doubles are passed back.By calling convention it is up to the callee to clean up any used stack space. In this case we didn't use any, but if we did then your compiler will translate your function
Add
in such a way that it cleans up the stack automatically.The code above is actually a hack in such a way that I use the GCC extended
asm
syntax to automatically put our variables into the appropriate registers. It will generate sufficient code around thisasm
call to make sure data is consistent.If you wish to use a stack based calling convention then
cdecl
is the standard oneThen we need to push the arguments to the stack prior to calling
One thing that I have not mentioned is that this
asm
call does not save any of our in-use registers, so I do not recommend putting this in a function that does anything else. In 32 bit x86 there is an instructionpushad
that will push all general purpose registers to the stack and an equivalent (popad
) to restore them. An equivalent for x86_64 is unavailable though. Normally when you compile C code the compiler will know which registers are in use and will save them in order for the callee not to overwrite them. Here it does not. If your callee uses registers that are in use by the caller - they will be overwritten!