インラインアセンブリを使用して、2つのメモリ位置をC変数に読み込み、2つのC変数を他のメモリ位置に格納する必要があります。私が書いたインラインコードは次のようになります。インラインCアセンブリが独自の変数を呼び出す
unsigned int us32 = (uint32_t)us;
__asm__ __volatile__("ldr %1, [%4, #0x10]\r\n" //read my 2 memory locations
"ldr %0, [%4, #0x18]\r\n"
"str %2, [%4, #0x14]\r\n" //write my 3 memory locations
"str %2, [%4, #0x18]\r\n"
"str %3, [%4, #0x10]\r\n"
: "=l" (leftover_time), "=l" (rollflag)
: "l" (us32), "l" (ena), "l" (s)
: "memory", "cc");
私のインラインコードから生成されたアセンブリは、しかし、動作するようには思えません。私はr2とr3に格納したい変数をロードして、ロードしようとしている変数をすぐに見つけ出します。これは私が時間の異なるインラインアセンブリのチュートリアルを読んで、私は&ダブルチェック私の入力/出力制約をチェックしましたし、私はちょうどよ、私はarm-none-eabi-objdump
us32 = (uint32_t)us;
c8e: 6bbb ldr r3, [r7, #56] ; 0x38
c90: 637b str r3, [r7, #52] ; 0x34
__asm__ __volatile__("ldr %1, [%4, #0x10]\r\n"
;;; These 4 instructions load the variables I want to write to memory
;;; into r2 and r3
c92: 2207 movs r2, #7
c94: 4b39 ldr r3, [pc, #228] ; (d7c <reschedule+0x16c>)
c96: 6819 ldr r1, [r3, #0]
c98: 6b7b ldr r3, [r7, #52] ; 0x34
;;; BOOM!! r2 and r3 have been clobbered, they no longer contain the
;;; values that I want to write (a constant #7 and unsigned in us32).
;;;
;;; The data that I want to read is indeed pointed by r1 + 16 and r1 + 24
c9a: 690b ldr r3, [r1, #16]
c9c: 698a ldr r2, [r1, #24]
c9e: 614b str r3, [r1, #20]
ca0: 618b str r3, [r1, #24]
ca2: 610a str r2, [r1, #16]
ca4: 633a str r2, [r7, #48] ; 0x30
ca6: 62fb str r3, [r7, #44] ; 0x2c
を使用してしまった以下の解体からかなり明確です私の頭を掻きながらここに座っている。誰かが私の間違いを捕まえることができます
私はarm-none-eabi-gcc
バージョン4.8.4
あなたのコードはフラグを壊さないので、あなたは '' cc ''clobberは必要ありません。メモリ出力オペランドを使用した場合、 ''メモリ ''クラバーを避けることもできます。 (clobberのドキュメントのようにすべてのストアをカバーするダミー構造体が示唆しているか、またはgccがアドレッシングモードを選択できるように各ストアの個々のメモリオペランドを指定するか、[[named] "r"(operands)もう一度番号を付け加えると混乱を避けることができます。 –
'strd'を同じレジスタで2回使うと、最初の2つのストアを1つの命令で実行できますか?いいえの場合は、#10と#14の店舗を並べ替えることができますが、それはインオーダーCPUで悪化します。 –
@PeterCordes "cc"フラグは、私が書いた他のコードから継承されています。私はそれらを削除します。名前付きレジスタと構造体についてのヒントをありがとう。また、m0 +を使用しているため、 'strd'を実行できません。これは、その命令をサポートしていません。 –