5

Windows VC ++に次のコードがある場合:

DWORD somevar = 0x12345678;
_asm call dword ptr [somevar]

AT&T構文を使用して、GCCインラインアセンブリで同じことを行うにはどうすればよいですか?

__asm__ __volatile__ (
    "call dword ptr [%%edx]" : :
    "d" (somevar)
);

このようなことを試しましたが、「ジャンク」エラーが発生します...

そして、いくつかのレジスタに渡して、それを、などに変換しようとしましたが、somevar動作させることができませんでした。dwordptr

更新:その場合、角かっこではなく括弧を使用する必要があるように見えるなど、便利なものを見つけました。また、lcallと呼ぶものを見つけましたfar。でも、どうやって再現できるのか、まだわかりませんdword ptr

4

1 に答える 1

7

AT&Tアセンブラ構文では、DWORDPTRなどを使用しないでください。オペランドの長さは通常、レジスタ名(ニーモニックに接尾辞を付けるオプションがあります)から取得されます。これは、asm()に指定するCオペランドのサイズから取得されます。これは、インラインアセンブラの非常に優れたプロパティです。これは、この例をx86_64またはi386アーキテクチャ用にコンパイルした場合に実行されることを意味します。最初のケースでは、アセンブリは次のようcall *%rdxになります。2番目のケースでは、次のようになりcall *%edxます。

#include <stdio.h>
void p()
{
    puts("Hallo");
}
typedef void (*fp)();
int main()
{
    fp var=&p;
    var();  
    // put 'var' in a register, the '*' says call indirect:
    asm volatile ("call *%0"::"r"(var));
}

AT&T構文を学ぶために、GCCが生成するコードを読むことができます(-Sでコンパイルしてみてください)。また、次のようなイントロをグーグルで検索してみてください。

警告: gccを使用したインラインアセンブリは簡単なことではありません。これは、他のほとんどのコンパイラを除いて、オプティマイザで動作するように設計されているためです。制約( "r")が何を意味し、何をするのかを本当に理解する必要があります。そうしないと、想像できない方法でコードが壊れてしまいます。「初期のクローバー」とは何かを答える前に、それを使用することを考えないでください。

于 2010-08-10T04:42:51.957 に答える