0

Now I am designing a function f(index,...) which will call #index entry in a function array passing the rest of parameters. If you see the function array as a service list, f acts like a service distributer.

f is written in assembly. It pops the first parameter index then calculates the corresponding target function address and jmp to it.

If I pass n parameters to f, the stack just holds n-1 ones when returning from the target function, because index was popped midway. For this reason, I cannot use cdecl convention, or the caller will clean the stack for n parameters by mistake.

stdcall should works. But the problem is that, since f has variable arguments, gcc seems __attribute__((stdcall)) f(index,...) unreasonable and reverts it back to cdecl.

So please could any one tell me how to declare f to be stdcall ?

JMAA
  • 1,730
  • 13
  • 24
Dappur
  • 59
  • 5

1 Answers1

0

I don't think using stdcall would solve your problem, since you would have to restore the stack anyway for your function to find the return address on the stack.

Rather than popping index from the stack, just leave it there. And either modify your target functions to ignore the first parameter, or move all the other parameters one position to the left before calling target function

HAL9000
  • 2,138
  • 1
  • 9
  • 20
  • Surely modifying the target functions to add a dummy parameters works, but not beautiful enough. And I cannot *move all the other parameters...* because `f` didn't know how many parameters passed in total. `stdcall` should works. In the implementation of `f`, it runs **leave** to recover `esp` and `ebp`, then **pop** the return address to register *#1*, saves `index` then replace it with *#1* (now the stack is constructed well). Finally it **jmp** to the target according to `index`. `stdcall` of the target will correctly clean the rest `n-1` parameters. – Dappur Jul 30 '18 at 04:18
  • Does 'f' have to be thread safe? Wrap `f` in a macro that saves `index` to a global variable before calling `f`. Or you could maybe use some inline assembly to pass `index` in a register. – HAL9000 Jul 30 '18 at 11:00