Я работаю над старой кодовой базой MUD с другом просто как проект хобби, но у меня возникают проблемы с получением кода для компиляции в любой ОС, кроме debian (в частности, x386). Проблема (в основном) из-за нескольких строк asm, которые я, честно говоря, недостаточно понимаю, чтобы изменить. Ошибка, которую я получаю при попытке компиляции в VS: «ошибка c2059: синтаксическая ошибка», строка 29. Есть идеи, как заставить это скомпилироваться в ОС x64?
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);
}
Это далеко не тривиально, поскольку x86-64 использует передачу регистров для аргументов [и это довольно уродливое решение, во-первых, поскольку в основном предполагается, что в регистры не передаются аргументы, а функция вызываемого объекта принимает все аргументы в стеке] ,
Я бы, вероятно, вообще избежал версии сборки и вместо второго цикла for (с кодом сборки) напишите что-то вроде:
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.
}
Маловероятно генерировать ужасно плохой код, если только MAX_FUNCTION_ARGS не ОЧЕНЬ велик [в этом случае вы, вероятно, захотите изменить соглашение о вызовах funcptr
на первом месте].