2017-05-16 15 views
1

私はCortex M3プラットフォームでGPIO0をリセットする関数を記述しようとしています。私はKeilコンパイラを使用しています。 目標はアドレス0x40041014に "1"を書き込むことです。私はコードを書いた:PUSHアセンブラ命令を使用できません

static void resetGPIO0() 
{ 
    __asm 
    { 
    MOV R0, #0x01 
    MOV R1, #0x1000 
    MOVT R1, #0x4004 
    STR R0, [R1, #0x14] 
    } 
} 

をし、それが働いていますが、私は私の関数はR0とR1に前にあった値をオーバーライドするという問題があります。私はスタックしてから戻ってPOPにプッシュしようとしたが、私は、関数の先頭に

PUSH {R0, R1} 

を追加するとき、私はエラーを取得:

1161: Cannot directly modify the stack pointer SP (r13).

は私が間違って何をしているのですか?

+3

'*(int型*)0x40041014 = 1; '? – Jester

+0

さて、問題は、このコードはに変換されていることである:[R1、#0x14の] BX LR と私ができるいくつかの本当に奇妙な理由のために MOVS R0、#0x01を LDR R1、[PC、#740] STR R0、そこにPCを使用しないでください –

+0

R0-R3はARM ABIによって呼び出し元に保存されます。 – EOF

答えて

2

ARMインラインアセンブリでは、レジスタR13、R14、およびR15はmay not be accessedです。これを行う場合は、インラインアセンブリを使用する代わりに、アセンブリ全体でプロシージャ全体を記述する必要があります。

0

PUSH命令が直接アクセスまたはR13は変更されませんが、それは間接的は、それを修正しない - ほぼ同じ機能で、コンパイラが生成するコードの問題を引き起こすことが保証されています。

コンパイラがあなた自身の組み込みを完全に正当なものとして拒否している理由がある場合は、PUSH命令(もちろん、あなた自身の責任において使用します)を発行すると、エラーメッセージの表現が間違っています。

残念ながら、ARMCCのエラーメッセージのドキュメントでは、このことについては何も言及していません。

(他の人が指摘したように、あなたは確かにない任意のレジスタを節約するコードをとにかくどんなアセンブラを書くために必要としません。)だけでやってと間違って何

関連する問題