私は何年にもわたって多くのアセンブラでアーム/サムをプログラミングしてきましたが、そこにある多くのディレクティブのほとんどを必要としませんでした。
.thumb_func は、別のレスポンダーが指摘したように非常に重要です。
例えば
.globl _start
_始める:
bリセット
リセット:
。腕
.globl 1
1:
r0、r0、#1 を追加
bx lr
。親指
.globl 2
2:
r0、r0、#2 を追加
bx lr
.thumb_func
.globl 3
三:
r0、r0、#3 を追加
bx lr
.単語 2
.単語 3
.arm または以前は .code32 または .code 32 のようなものであったため、これは親指コードではなく腕のコードであり、cortex-m3 では使用する必要はありません。
.thumb 同様に、以前は .code 16 であったか、またはそれがまだ機能している可能性があります。同じ取引により、次のコードの親指がアームではなくなります。
使用しているラベルが、他のファイルから、または間接的に分岐する必要があるグローバル ラベルでない場合、.thumb_func は必要ありません。しかし、これらのグローバル ラベルの 1 つへの分岐のアドレスを適切に計算するには (lsbit は親指の場合は 1 で、腕の場合は 0 です)、それを親指または腕のラベルとしてマークし、thumb_func でそれを行います。コードを追加して分岐する前にそのビットを設定する必要があり、ラベルは C から呼び出すことができません。
00000000 <_start>:
0: eaffffff b 4 <1>
00000004 <1>:
4: e2800001 追加 r0、r0、#1
8: e12fff1e bx lr
0000000c <2>:
c: 3002 は、r0、#2 を追加します
e: 4770 bx lr
00000010 <3>:
10: 3003 は r0、#3 を追加します
12: 4770bxlr
14: 0000000c andeq r0, r0, ip
18: 00000011 andeq r0, r0, r1, lsl r0
.thumb までは、アセンブラは必要に応じてアーム コードです。
2 番目と 3 番目のラベル/関数の両方が必要なサム コードですが、2 番目のラベルには偶数番号のアドレスがあり、3 番目のラベルには適切な奇数番号のアドレスがあります。
最新の codesourcery ツールを使用して、上記のサンプルをアセンブル、リンク、およびダンプしました。
すべてがthumb(/thumb2)であるcortex-m3では、thumb_funcはそれほど重要ではないかもしれません.コマンドラインスイッチで動作するだけかもしれません. 親指のみのプロセッサから通常のアーム/親指コアに移行する場合に備えて、これは良い習慣です。
一般に、アセンブラーは、これらすべてのディレクティブを追加したり、物事を高水準言語のように見せたり感じたりする他の方法を追加することを好みます。それらを使用する必要はないと言っているだけです。私はアーム用のアセンブラを切り替え、多くの異なるプロセッサ用に多くの異なるアセンブラを使用し、より少ないアプローチを好みます。つまり、アセンブリ自体に焦点を当て、ツール固有のアイテムをできるだけ少なく使用することを意味します. ただし、私は通常、ルールではなく例外であるため、コンパイラ出力が生成するディレクティブを調べることで、より頻繁に使用されるディレクティブを把握できます (ドキュメントで確認します)。
unsigned int one ( unsigned int x )
{
戻ります(x+1);
}
.arch armv5te
.fpu ソフト vfp
.eabi_attribute 20、1
.eabi_attribute 21, 1
.eabi_attribute 23、3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30、2
.eabi_attribute 18、4
.file "bob.c"
。文章
.align 2
.グローバルなもの
.type one, %function
1:
.fnstart
.LFB0:
@引数= 0、ふり= 0、フレーム= 0
@ frame_needed = 0, uses_anonymous_args = 0
@リンク登録保存を廃止。
r0、r0、#1 を追加
bx lr
.fnend
.size one, .-one
.ident "GCC: (Sourcery G++ Lite 2010.09-50) 4.5.1"
.section .note.GNU-stack,"",%progbits
.align を使用するのは、アームとサム アセンブラ、またはデータをアセンブラと混合する場合です。このようなプラットフォームのアセンブラは、サム命令がハーフワード境界にあり、アーム命令がワード境界に位置合わせされているなど、明らかなことを認識していると思われます。ツールは必ずしもそれほどスマートではありません。.aligns をまき散らしても害はありません。
.text はデフォルトであるため、少し冗長ですが、害はありません。.text と .data は標準の属性です (arm に固有のものではありません) ターゲットで rom と ram の組み合わせをコンパイルする場合、気にするかもしれません (リンカー スクリプトで何をするかによって異なります)。 .
.size 明らかに関数のサイズは、そのディレクティブから始まります。アセンブラはこれを独自に把握することはできないため、この関数のサイズがコード、リンカ スクリプト、デバッガ、ローダーなどにとって重要な場合は、これを正しくする必要があります。それ以外の場合は、気にする必要はありません。関数は高レベルの概念ですが、アセンブラーには実際には関数がなく、サイズを宣言する必要はありません。そして、Cコンパイラは確かに気にしません。分岐先のラベルを探しているだけで、アームファミリの場合、分岐先のサムコードまたはアームコードです。
長いコードで即値 (ldr rx,=0x12345678) を処理するのが面倒な場合は、.pool ディレクティブ (より新しい同等のものがあります) が便利です。ここでもまた、このデータを無条件分岐の後に配置するほどツールが常にスマートであるとは限りません。私は怠惰な半分真剣に言います。label: .word のことを常に行うのは苦痛であり、arm ツールと gcc ツールの両方でそのショートカットが許可されていると信じているため、他の人と同じように使用しています。
また、llvm は追加の .eabi_attribute を 1 つまたは 2 つ出力します。これは、コード ソースのバージョン/mods でサポートされているが、gnu でリリースされた binutils ではサポートされていません (おそらくまだ)。動作する 2 つの解決策は、llvm の asm print 関数を変更して eabi_attributes を書き込まないようにするか、少なくともコメント (@) を付けて書き込むか、コード ソースから binutils source/mods を取得してそのように binutils をビルドすることです。コード ソースは gnu (たとえば、thumb2 のサポート) をリードしたり、新しい機能をバックポートしたりする傾向があるため、これらの llvm 属性はメインラインの binutils に間もなく存在すると思います。llvm コンパイル済みコードから eabi_attributes を削除しても、悪影響はありませんでした。
上記の同じ関数の llvm 出力は次のとおりです。これは明らかに、eabi_attributes をコメントアウトするために変更した llc です。
.syntax 統一
@ .eabi_attribute 20, 1
@ .eabi_attribute 21, 1
@ .eabi_attribute 23, 3
@ .eabi_attribute 24, 1
@ .eabi_attribute 25, 1
@ .eabi_attribute 44、1
.file "bob.bc"
。文章
.globl 1
.align 2
.type one,%function
1つ: @ @1つ
@ BB#0: @ %entry
r0、r0、#1 を追加
bx lr
.Ltmp0:
.size one、.Ltmp0-one
elf ファイル形式は十分に文書化されており、elf 固有のディレクティブ (存在する場合) が何を行っているかを実際に確認したい場合は、非常に簡単に解析できます。これらのディレクティブの多くは、何よりもリンカーを支援するためのものです。.thumb_func、.text、.data など。