__irqは、ARM7(v4) アーキテクチャの割り込みサービス ルーチン関数を定義するために使用されることを理解しています。しかし、それは関数にどのような変更を加えますか?
ARMインフォメーションセンターによると:
__irq キーワードを使用すると、C または C++ 関数を割り込みルーチンとして使用できます。__irq は関数修飾子です。関数の型に影響します。
ARM コンパイラは、 __irq関数修飾子で定義されたルーチンにどのような特別な処理を提供しますか??
__irqは、ARM7(v4) アーキテクチャの割り込みサービス ルーチン関数を定義するために使用されることを理解しています。しかし、それは関数にどのような変更を加えますか?
ARMインフォメーションセンターによると:
__irq キーワードを使用すると、C または C++ 関数を割り込みルーチンとして使用できます。__irq は関数修飾子です。関数の型に影響します。
ARM コンパイラは、 __irq関数修飾子で定義されたルーチンにどのような特別な処理を提供しますか??
コンパイラは、関数の出口/入り口を変更します。これは、lr を調整し、リターン後にプロセッサ モードを変更し、通常は関数呼び出し間で保存されないレジスタ (通常は r0-r3 および r12) を保存および復元することを意味します。以下に短い例を示します。
void func()
{
...
}
生成されたアセンブラー:
/* void func() */
stmfd sp!, {r4, lr}
...
ldmfd sp!, {r4, lr}
bx lr
IRQ と同じ機能:
/* void __attribute__ ((interrupt ("IRQ"))) func() */
sub lr, lr, #4
stmfd sp!, {r0, r1, r2, r3, r4, r5, ip, lr}
...
ldmfd sp!, {r0, r1, r2, r3, r4, r5, ip, pc}^
そしてFIQとして:
/* void __attribute__ ((interrupt ("FIQ"))) func() */
sub lr, lr, #4
stmfd sp!, {r0, r1, r2, r3, r4, lr}
...
ldmfd sp!, {r0, r1, r2, r3, r4, pc}^
正確なレジスタ リストは、ABI などの一部の外部パラメータにも依存することに注意してください。
gccマニュアルより
この属性が存在する場合、コンパイラは、割り込みハンドラでの使用に適した関数の開始および終了シーケンスを生成します。
armcc も同じことを行うと思いますobjdump
。作成されたバイナリの違いを確認するために使用できます。
あなたが参照したページから:
AAPCS で通常保存されるレジスタだけでなく、浮動小数点レジスタを除くすべての破損したレジスタが保存されます。デフォルトの AAPCS モードを使用する必要があります。