2

私は iPhone/iPad プロジェクトに取り組んでおり、いくつかの (すべてではない) 算術演算中にステータス レジスタを更新したいと考えています。デフォルトでは、Xcode は「Compile for Thumb」を使用しますが、これを変更したくありません。

次の GCC インライン アセンブリ コードは ARM では正常に動作しますが、Thumb ではコンパイル エラーが発生します:「命令は Thumb16 モードでサポートされていません - r6、r4、r5 を追加します」。問題は、ステータス レジスタの更新にあります。(私もそれを認識してmovcsおり、strcs変更する必要があります)。

Thumb には、CPSR でオーバーフロー (V) またはキャリー (C) を設定する ADD 命令がありますか? そうでない場合、オーバーフローとキャリーをテストする Thumb 固有のアセンブリ レベルの回避策はありますか?

uint32_t result, a, b;
int no_carry = 1;
...

__asm__
(
  "ldr  r4, %[xa]   ;"  // R4 = a
  "ldr  r5, %[xb]   ;"  // R5 = b
  "adds r6, r4, r5  ;"  // R6 = R4 + R5, set status
  "movcs    r4, #0      ;"  // set overflow (if carry set)
  "strcs    r4, %[xc]   ;"  // store it (if carry set)
  "str  r6, %[xr]   ;"  // result = R6
  : [xr] "=m" (result), [xc] "=m" (no_carry)
  : [xa] "m" (a), [xb] "m" (b)
  : "r4", "r5", "r6"
);

...

編集: ARM アーキテクチャのアプリケーション バイナリ インターフェイス (ABI) で ARM ABI を利用するには、レジスタも移動する必要があります。

4

3 に答える 3

4

Igor は「.syntax_unified」を提案しました。ただし、少なくとも binutils 2.22 では、コマンドは「.sytax 統合」です。次の例は、ここで問題なくコンパイルされます。

.align  4
.code   16
.syntax unified

adds r0,r0,r2
adc  r1,r1,r3
于 2012-05-31T21:27:04.470 に答える
4

私は XCode と Apple のツールチェーンにあまり詳しくありませんが、UAL 以前の古い形式のアセンブリを期待している可能性があると思います。ADD の Thumb-16 エンコーディングでは常にフラグが設定されます (レジスタ R0 ~ R7 用)。(ほとんどの算術演算は常に Thumb-16 のフラグを更新するため、S が暗示されていました。)したがって、.syntax_unifiedアセンブリ ブロックの先頭に追加するか、単純な ADD ニーモニックを使用するようにしてください。

ただし、コードには別の問題があります。Thumb-16 は条件付き命令をサポートせず、条件付き分岐のみをサポートします。そのため、ブランチを使用してコードをやり直すか、ADC/SBC を使用する必要があります。

上記はすべて元の Thumb ISA (別名 Thumb-16) にのみ適用されることに注意してください。Thumb-2 (別名 Thumb-32) は、上位レジスタや条件付き命令の使用など、ARM でできることは (ほぼ) 何でもできますが、ARMv6 ターゲットでは使用できません (おそらく XCode のデフォルトです)。

于 2011-06-20T10:21:22.280 に答える
0

Thumb-16 クイック リファレンス ガイドによると、ADDS手順が利用できるはずです。これはアセンブラのバグのようです (@dwelch で確認済み)。

アセンブラ ディレクティブを使用して事前にエンコードされた命令を発行することで、この問題を回避できることがわかりました。例えば:

__asm__
(
  "ldr  r0, %[xa]   ;"  // R0 = a
  "ldr  r1, %[xb]   ;"  // R1 = b
  "adds r1, r1, r0  ;"  // R1 = a + b
  ...
);

以下を使用して実現されます。

__asm__
(
  "ldr  r0, %[xa]   ;"  // R0 = a
  "ldr  r1, %[xb]   ;"  // R1 = b
  ".inst.w 0x1809   ;"  // Issue 'adds r1, r1, r0'
  ...
);

必要に応じてadds r2, r2, r1、コードは を発行する必要が.inst.w 0x1852あります。

編集: arm thumb2 ldr.w 構文のためにコードが最近更新されましたか? Binutils メーリング リストで。

于 2011-06-23T04:24:26.353 に答える