2

私は友人と趣味のプロジェクトとして古い MUD コードベースに取り組んでいますが、debian 以外の OS (具体的には x386) でコードをコンパイルするのに問題があります。この問題は (主に) 私が正直に言って変更するほど十分に理解していないいくつかの asm 行が原因です。VS でコンパイルしようとしたときに受け取るエラーは、「エラー c2059: 構文エラー」29 行目です。これを 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);
}
4

1 に答える 1

3

x86-64は引数にレジスタ渡しを使用するため、これは簡単なことではありません[そして、基本的にレジスタに引数が渡されず、呼び出し先関数がスタック上のすべての引数を取ると仮定しているため、そもそもかなり醜い解決策です] .

私はおそらくアセンブリ バージョンを完全に避け、2 番目の 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、最初に の呼び出し規約を変更する必要があります]。

于 2014-04-26T23:04:38.740 に答える