2

I'm working on an old MUD codebase with a friend just as a hobby project, but I'm having issues getting the code to compile in any OS other than debian (x386 specifically). The issue is (mostly) because of a few asm lines that I honestly don't understand enough to modify. The error I receive when trying to compile in VS is "error c2059: syntax error '' line 29. Any idea on how to get this to compile on an x64 OS?

void        Execute(int nArgs, ...)
{
    if(MAX_FUNCTION_ARGS < nArgs)
        throw "Error: CFuncPtr has too many args";

    int i;
    void *fptrs[MAX_FUNCTION_ARGS], *ptrs[MAX_FUNCTION_ARGS];
    va_list ap;
    va_start(ap, nArgs);

    for(i = 0; i < nArgs; i++)
        fptrs[i] = va_arg(ap, void *);
    for(i = 0; i < nArgs; i++)
    {
        ptrs[i] = fptrs[nArgs - i - 1];
// ============== This is the part with the issue
        asm volatile("" \                         // This is line 29.
                "movl   %0, %%eax\n\t" \
                "pushl  %%eax\n\t" \
                :                       
                : "r"(ptrs[i])
                : "%eax");
// ==============
    }
    (*funcptr) ();
    va_end(ap);
}
Paul McDowell
  • 154
  • 1
  • 10

1 Answers1

3

This is far from trivial, since x86-64 uses register passing for arguments [and it's a rather ugly solution in the first place, since it's basically assuming no arguments are passed in registers, and that the callee function takes all arguments on the stack].

I would probably avoid the assembly version altogether, and instead of the second for-loop (with the assembly code) write something like:

switch(nArgs)
{
  case 0:
     (*funcptr)();
     break;
  case 1: 
     (*funcptr)(fptrs[0]);
     break;
  case 2:
     (*funcptr)(fptrs[0], fptrs[1]);
     break;
  ... Repeat until MAX_FUNCTION_ARGS is covered.
}     

It is unlikely to generate terribly bad code unless MAX_FUNCTION_ARGS is VERY large [in which case you probably want to change the calling convention of funcptr in the first place].

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thank you for the assistance! The MAX_FUNCTION_ARGS goes is 8, so not too long for the switch (but I understand the poor code issue, it's fairly common in this codebase). I considered trying to port the MUD to a fresh codebase but I honestly think working on modernizing old code will help make me a better programmer and help me learn more about C++. Again, thanks for the help! – Paul McDowell Apr 26 '14 at 23:15
  • 1
    Rewriting existing code (part by part, with plenty of testing) is a very good way to learn - both in the sense that you learn to read (other people's?) code and in that you learn how to solve common problems. Both of which are very useful skills - but of course, you do then need to have a good set of tests to determine that what you have done is correct! – Mats Petersson Apr 26 '14 at 23:19