2016-10-02 5 views
-1

コンパイラがさまざまな方法でコードを生成するので、どのようにC言語とアセンブリを混在させることができますか?たとえば、多くのCコンパイラは、関数呼び出し時にスタックにプッシュするのではなくレジスタを使用します。 C関数を呼び出す代わりにレジスタを設定するのではなく、スタックに引数をプッシュする別のコンパイラによって作成されたオブジェクトファイルを使用してアセンブリコードを作成したりリンクしたりすると、メモリの場所が適切になります。Cとアセンブリどのように動作するのですか?

私の推測では、Cコンパイラアセンブリの出力はそれほど巧妙なやり方で行いましたが、違いはなく、まだ動作しますが、表示されないアセンブリコードを確認することはできませんそれは動作します。

私はコンパイラを書いているので誰でも私の質問に答えることができ、これを知る必要があるので、将来私はCモジュールとリンクしたいと思います。

+0

Cコードとアセンブリコードは、同じ呼び出し規約に従う必要があります。彼らが別のコンベンションを使用している場合は、予期しない動作が発生する可能性があります。 –

+0

_ "多くのCコンパイラは、関数呼び出し中にスタックにプッシュするのではなく、レジスタを使用します。コンパイラが従う "呼び出し規約"があります。 –

+0

ちょうどそれが言及している:*インラインアセンブリ*は必ずしも**任意の**呼び出し規約を遵守する必要はありません、レジスタの使用法だけで(私はそれを好むとは思わない) – tofro

答えて

1

関数の呼び出しに使用される規則は、「アプリケーションバイナリインターフェイス」(ABI)の一部です。このインターフェイスがと指定されている場合、仕様に準拠するすべてのコードをリンクできます。

C言語の標準ABIはありませんが、ほとんどの一般的なプラットフォームでは、デファクトスタンダードABIを効果的に生成する1つの一般的なCコンパイラがあります(Windowsの場合は1つ、x86の場合は32ビットと64ビット)。 1つはARMのLinux用など)。 ABIは、多数の別々の "呼び出し規約"を指定することがあります.Cコンパイラは、通常、ベンダー拡張を使用して関数宣言のポイントで目的の規約を指定できるようにします。

逆に、Cコンパイラのドキュメント化されたABIやオブジェクトコードの既存のビットがない場合は、一般的にはそれを正常にリンク(または相互作用)することはできません。

+0

私は本質的にこのインタフェースがより仕様であることを理解しています。私が選択した仕様と互換性のあるコードを生成するために私のコンパイラを書くべきです。 –

+0

@ダニエル - あなた自身のコンパイラを書くならば、これはあなたの選択であり、好きな呼び出し規約を使うことができます。ローカルのCコンベンションに適応することは別のことかもしれません。例えば、C++では 'func'をC言語と互換性を持たせるために' extern "C" void func(); 'と書いています。 –

関連する問題