4

アセンブラで書くと、コードサイズと実行時間が短縮されます。しかし、十分なメモリと十分な時間があるとします。C コードだけを使用してデバイスを起動できますか? つまり、電源を入れてから、C コードを直接実行します。特に ARM プロセッサに興味があります。

4

4 に答える 4

6

実際には、ARM のCortex-M3 マイクロコントローラー用の C のみのファームウェアを作成できます。そのベクター テーブルにはスタック ポインターのエントリが含まれているため、その値はプロセッサによって初期化され、コンパイルされたコードをリセットからすぐに使用できます。周辺機器をセットアップし、C ライブラリ環境を初期化する必要がありますが、アセンブラーで行う必要はありません。また、Cortex-M3 は、割り込みハンドラ エントリで揮発性レジスタを自動的に保存するため、C で直接書き込むこともできます。

とはいえ、ほとんどのコンパイラ ベンダーは、最も制御しやすいアセンブラで記述されたスタートアップを提供しています。

于 2012-05-24T10:32:26.260 に答える
4

前述のように、cortex-m3 は特別であり、そのようなことを可能にします。1 つの例外を除いて、C コードを呼び出すためのベクトル テーブルを作成するには、asm またはその他の魔法が必要です。

一般的に答えはノーです。組み立てが必要です。プロセッサは一般的であり、通常、プログラム、データ、スタックなどに設定したアドレス空間を認識していません。レジスタ、特にスタックポインタは、ゼロなどの既知の値に初期化されることがよくあります。プロセッサには一般に、起動シーケンスがあることが知られています。これには、実行を開始するアドレス、または実行を開始するアドレスを見つけるアドレスがあります。そのアドレスのテーブル、リセット用、割り込み用などは、ブートコードのプログラマーによってそこに配置されますが、C で管理することは可能ですが、努力する価値はありません。そのベクトルを構築するために asm の数行を書く方がはるかに簡単です。テーブル。(これはcortex-mの場合です)

したがって、少なくともスタック ポインタを設定し、エントリ C コードに分岐する必要があります。そこからおそらく C を実行することができます。これがアームであり、cortex-m でない場合は、複数のスタックをセットアップする必要があります。 (割り込みを使用したい場合、障害を処理したい場合など)、そのセットアップを実行するには特定のasm命令を使用する必要があるため、asmは実数またはインラインで必要です。

.data を使用する習慣がある場合、または .bss がゼロになることを期待している場合は、何かを実行する必要があります。一部のコードで bss をゼロにして .data を準備する必要があります。通常、システム (デスクトップ/ラップトップでも) はフラッシュから起動します。.data がフラッシュにある必要がありますが、読み取り/書き込みが必要な場合は、そのデータをフラッシュからコピーする必要があります。それを行うには、最初にRAMを起動して実行する必要があります(以下を参照)。

古き良き時代ではありませんが、今日のドラムでは、電源を入れてメモリを使い始めることはできません。ドラムを起動して実行するには、多くのコードが必要です。はい、このコードは C で書かれており、おそらく asm ではありません (ただし、パフォーマンス上の理由から、C コンパイラに生成させるとは限らない特定の命令を活用するために asm を使用する場合があります)。

したがって、必ずしも腕に固有ではなく、一般的にさまざまなシナリオがあります。すべてではありませんが、いくつかのニュアンスをリストします

1) 初期化する必要のない sram または内部 ram を使用するシステムがあり、.data を使用しておらず、コードは .bss がゼロ化されていると想定していません。一般的には、スタック ポインターを初期化し、C エントリ ポイント (メイン、または任意の名前) に分岐することが最低限必要です。

2) 初期化する必要のない sram または内部 ram を使用するシステムがあり、C コードを開始する前にそこにあると予想される .data を使用しており (C プログラマーにとっては非常に一般的です)、.bss を前にゼロにする必要があります。あなたのCコードが始まります(これも典型的ですが、ありがたいことにgccはこれを行うコードについて不平を言い始めています)。この場合の C コードは、C コードが実行される前にこれらが準備されることを期待しているため、.bss のゼロ化と、フラッシュから RAM への .data のコピーが asm で行われます。これは最も一般的なシナリオです。さまざまなプロセッサの crt0.s ルーチンの多くを見てください。これは共通のテーマであり、スタック ポインターを設定し、bss をゼロにし、.data ブランチをメインにコピーします。

3) 初期化する必要のない内部 sram を備えたシステムを使用しているが、使用する予定のメイン メモリは dram です。これは 2 つのステップです。最初のブートローダーはスタック ポインターを設定する必要があります。オプションで .bss をゼロにし、好みに応じて .data をコピーしてから、最初のブートローダーのエントリ ポイントに分岐します。このブートローダはドラム システムを立ち上げます。このブートローダは、必要に応じて .data とゼロの .bss をコピーできるようになり (これは現在 C で実行できます)、メインのブートローダ エントリポイント/関数に分岐します。これは、より大きなメイン メモリを想定して使用します。

4) マイクロコーディングを備えた x86 プロセッサを使用している場合、起動時にマイクロコードにパッチを適用する必要があります。これについて個人的な知識はありませんが、マイクロコーディングを変更しているため、使用する命令の数が限られていると想定します。または、RAM にコピーしてから少し反転すると、魔法のようにパッチが切り替わり、変更を加えて実行されるかどうかはわかりませんが、アセンブリが必要になるに違いありません。

多くの C ライブラリ呼び出しがアセンブリにあることに注意してください。したがって、C はアセンブリ、特に腕のアセンブリです。すべての除算、乗算、モジュロ、浮動小数点などを避けていますか? 文字列関数やコピー関数を使用したことはありませんか。C ライブラリ呼び出しをまったく使用しますか? あなたが使っていて、それを知らなかったasmがある可能性があります。memcpy は、多くの場合、asm では手動で調整され、アームでは esp が調整されます。また、コードで構造体を使用する場合、コンパイラーは、それらの使用内容と使用方法に応じて、memcpys でスローできる/スローします。除算し、確実に asm を法とします。時々増殖する。浮動小数点、多くの場合 asm、fpu があっても。確かに、この asm を自分で作成したわけではありませんが、そこにはおそらく asm があり、その asm がなければブートローダーは存在しません (これらのライブラリを使用している場合)。

ブートローダーのアセンブリのみを意味するタイトルの質問は誤りです。ブートローダーはほとんどアセンブリではありません。ほとんどの場合、いくつかのアセンブリが必要です。

cortex-m は、特別な命令や asm で割り込みをラップする必要がないように設計されているため (またはコンパイラにそれを行わせる)、ユニークな獣です。典型的ではありません。ただし、cortex-m には大規模から巨大なベクトル テーブルがあります。Cでそのテーブルをどのように構築するのか興味があります.私はそれを行う方法をいくつか持っていますが、asmは実際にはasmではなくても、asmはアセンブラへのディレクティブです(.word this_handler、.word that_handler) .

従来のアームの 32 ビット ARM7 のような命令 ARM コアでは、コンパイラ ゲームをプレイしない限り、スタックをセットアップし、少なくとも asm で C コードに分岐する必要があります。

この質問の根源について疑問に思う必要があります。ブートローダーは、プロセッサと周辺機器に非常に密接に結びついています。ブートローダーを作成するプログラマは、ハードウェア レジスタなどを快適に操作できる必要があります。これは、そのプロセッサの命令セットをある程度快適に使用できることを意味します。ブートローダーですべての asm を回避することは懸念事項です。ベクトル テーブルから C コードに直接移行できるという理由だけで cortex-m を使用しても、使用しているコンパイラが汎用アーム呼び出し規則だけでなく、ハードウェア呼び出し規則に準拠していることを検証する必要があります。特定の範囲のレジスタが保持され、リターン時に適切な命令が使用されることを保証するため。つまり、このレベルでは、コンパイラが生成したコードを逆アセンブルし、手動/視覚的に検査することを意味します。

于 2012-05-25T02:06:31.800 に答える
1

私も正確な答えはわかりません。私が考えることができるいくつかの理由を提案します (マイナスメモリと効率):
- コードはデバイスに非常に固有であり、他の場所でコンパイルして実行する必要はありません
- 特別な命令へのアクセス (?)
- ブートローダーが起動したときの状態通常のプログラムとは違う(?)(スタック、ヒープ)

免責事項: この回答には間違った情報が含まれている可能性があります。ここでは何も真剣に考えないでください。

于 2012-05-24T05:34:49.283 に答える
1

ブートローダーは、起動時にデバイスを初期化する責任があります。この時点では、アセンブラしか利用できません。多くの場合、アセンブラ部分は可能な限り小さく保たれ、システムの初期化を担当するため、オペレーティング システムの一部や最小限の C ランタイムなどをメモリにロードして実行できます。この時点の後、他の初期化タスクは、たとえばC.

役に立つかもしれないいくつかのリンク:

ウィキペディアのブートローダー エントリ

U ブーツの設計原則

これが役に立てば幸いです。

于 2012-05-24T05:52:54.170 に答える