2016-03-24 11 views
2

このことについての説明はありません。このようなコードを書いてbarと呼ぶとどうなりますか?否定的な結果はありますか?ARMアセンブリのプロシージャ(PROC/ENDP)の外部に分岐することはできますか?

foo PROC 
    ... 
    BX lr 
    ENDP 

bar PROC 
    B  foo 
    ENDP 

UPDATE

Techicallyそのようなことを行うために、完全に合法です。コードはコンパイルされ、正しく動作します。いくつかの人々が気づいたように、PROCディレクティブは、オブジェクトファイル内のいくつかのメタ情報に必要です。私はそのような方法で(上記の例のように)それを使用することによって、私は潜在的に未知の結果でこの情報に「ダメージを与える」ことができるのではないかと恐れています。

このディレクティブの説明は

アセンブラはELFのためのDWARFコールフレーム情報を生成するときに、関数の開始を識別するために、PROCを使用していることを言います。 PROCは、カノニカルフレームアドレスをR13(SP)に設定し、フレームステートスタックを空に設定します。

私はデバッガの仕組みが良くありませんが、私が間違っていないのであれば、コールフレームはスタックに関連するものを意味します。私の機能でスタックを使用しないので、私はこの情報が私にとって重要ではないという結論を下すことができます。私は正しい?

+0

使用しているチップアーキテクチャとアセンブラは何ですか? –

+1

否定的な結果はありますか?あなたがこのようにプログラムするなら、あなたは混乱した混乱に終わるでしょう。 –

+0

'bar'のCバージョンが' void bar(){foo();}だったらこれはいいでしょう。 ''(つまり、 'bar'は' foo'の呼び出しで終わります。したがって 'foo'は' bar'に戻り、 'bar'を呼び出し元に返すのではなく' bar'を呼び出した人に戻ります。さもなければ、これをしないでください。 – Michael

答えて

3

PROCのような注釈は、ツールの利益のためである。そのラベルに対して生成されたELFシンボルがデータではなく関数としてマークされるべきであることを示します。リンク、デバッグなどの目的で、すべてのオブジェクトファイルのメタ情報が必要です。ダイナミックローダーにどのようにセグメントをマップするかを通知するため、実行中の実際のコードとデータには関係しません。

別の方法で考える:関数呼び出し自体は単なる分岐なので、何らかの形で命令セットレベルで "関数"の外に分岐することが許可されていない場合、実際にどのような有用なコードを書くことができますか? ;)

+0

ドキュメントでは、「アセンブラは、ELFのDWARF呼び出しフレーム情報を生成するときに、PROCを使用して関数の開始を識別します。だからあなたはメタ情報について正しいです。しかし、デバッガ、リンク、ローダの使用は本当に重要ですか?私はデバッガの仕組みがあまり良くありません。 –

+0

Thumbコードとして 'foo'をビルドしたとします。リンカは、' 'シンボルの種類がわからず、適切なインターワーキングのためにボトムビットを設定するのではなく、実際の命令アドレスで' blx foo'再配置を行いますあなたは悪い時を過ごすでしょう。その後、予期せぬクラッシュをデバッグしようとすると、デバッガもARM命令として逆アセンブルして、ぎこちなく表示しようとします; – Notlikethat

0

これは完全に合法です。コンパイラは、あまりにも、時々このようなコードを生成します。

int foo(int x) 
{ 
    return x*x*4 + x*7 + 1; 
} 

int bar(int x) 
{ 
    printf("Hello bar"); 
    return foo(x); 
} 

このコードではなく、コールのバーの中からfooへのジャンプとして実装される可能性が非常に高いですし、すぐに戻ります。

+0

これは意味があります。コンパイラがそのようなジャンプを生成することができるなら、私はそれを行うこともできます! –

関連する問題