2017-10-20 7 views
1

C++コードに外部.ASMファイルをインクルード?は、次のようにソースコードを含めることが可能である

+0

asmファイルをコマンドラインusuall(gccなど)に追加すると、正しく処理されますほとんど)、バイナリに追加されます。それをC(++)に含めると、インラインアセンブリーでない限りは使えません。 –

+0

異なるコンパイラは、インラインアセンブリのサポートが異なります。私が知る限り、標準的なC++ [asmキーワード](http://en.cppreference.com/w/cpp/language/asm)を使用する人はいませんが、おそらくいくつかあります。 PCには、IntelとAT&Tの2つの主要なアセンブリ言語構文があります。あなたはそれにも対応しなければなりません。アセンブリコードとアセンブリを別々にアセンブルするのが最も良い方法です。 –

+1

あなたの質問への直接答えはいいえ – Asesh

答えて

2

TL:DR ほとんどのコンパイラでは、はありません。asmソースファイルをグローバルスコープのasm文の中に入れることができない限り、そうではありません。それから確かに、なぜ迷惑だ。別々にasmを構築する方が一般にはるかに優れています。


GNU Cのinline-asm構文を使用すると、任意のアセンブリをグローバルスコープに配置して、コンパイラによって生成されたasmと一緒にアセンブルできます。任意のC/C++関数外でasm("instructions and assembler directives ...");を使用してください。 (GAS構文asmソース)を含めると、その処理を行うには、.Sの事前処理された内容をC++ソースで取得する必要があります。これは不可能です。C/C++, can you #include a file into a string literal?


あなたは実際はそれがうまくいく、その時点でsrc.Sの内容が含まれるであろう方法で、この

int foo() { return 0; } 

asm ("#include \"src.S\" "); // doesn't work 

ような何かを書くことができます。あなたは文字通り、これを使用する場合は、compiler's asm output will be:アセンブラへの入力で

 .file "example.cpp" 
     .text 
.Ltext0: 
#APP 
     #include "src.S" 
#NO_APP 

# omitted some .directives 
foo: 
    xorl %eax, %eax 
    ret 

# is the comment character in GNU as syntax for x86、そう#include "src.S"は単にコメントとして扱われます!

gcc foo.Sfoo.Sfoo.sを生成する)でCプリプロセッサを実行してからアセンブラに供給します。しかし、これはコンパイラが生成するasm出力では起こりません。コンパイルする前にC/C++ソースのみがCPP経由で供給されます。


あなたは正確にあなたがasm文の本体内に記述します。何のように、二重引用符内のすべての行をラップのasmソースファイルを書くことができます。

例えば、bar.inline-asm

".p2align 4      \n\t" 
".globl bar      \n\t" 
".type bar, @function   \n\t" 
"bar:       \n\t" 
"  lea (%rdi,%rsi,2), %eax \n\t" 
"  ret      \n\t" 
".size bar, .-bar    \n\t" 

は(これは GNU C Basic ASMであることに注意してください、私たちは %文字を倍増する必要はありません。)することができ、この src.c

が、我々はそれをテストすることができます:

// extern "C" // if this is in C++. 
int bar(int a, int b); 

asm(
#include "bar.inline-asm" 
); 


int main(void) { 
    return bar(2, 4); 
} 

私はこれをテストし、それが動作:

[email protected]:~/src/SO$ gcc -Wall -O2 include-asm.c 
[email protected]:~/src/SO$ ./a.out; echo $? 
10 
# correct result for 2 + 4*2 

$ disas a.out  # alias for objdump -drwC -Mintel 

... 
0000000000000530 <main>: 
530: be 04 00 00 00   mov esi,0x4 
535: bf 02 00 00 00   mov edi,0x2 
53a: e9 11 01 00 00   jmp 650 <bar>  # optimized tail-call to bar() 
53f: 90      nop 

... 
0000000000000650 <bar>: 
650: 8d 04 77    lea eax,[rdi+rsi*2] 
653: c3      ret  
654: 66 2e 0f 1f 84 00 00 00 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 
65e: 66 90     xchg ax,ax 

明らかに、この場合は、最後に一緒にリンクされた別々のオブジェクトファイルを構築するために、これを行うことには全く利点がありません。つまり、gcc -O2 foo.c asm.Sです。

ネームマングリングはそれほど簡単ではありません。_bar(Windows)対bar(Linux)の状況は単純化されません。 (Agner Fog's calling conventions PDFと、asmの最適化ガイドを参照してください。

+0

私はWindows上でOPが動作していることを知っていますMSVC –

+0

@MichaelPetch:それは私の推測でしたが、彼らは言わなかったし、GNU Cインラインasm構文の半面白い答えがあります。 MSVCのグローバルスコープで '__asm {#include"なんでも "}'は動作しますか?または、決してあなたが呼び出さないダミー関数の中でそれを行うことができますか? –

+1

32ビットMSVC/C++の '__asm {}'ステートメント(インラインアセンブリ)は、グローバルスコープでは使用できません。 64ビットコードでは、 '__asm {}'はこれ以上サポートされません。 –

関連する問題