2014年10月27日月曜日

__attribute__((naked)) の意味:prologue コードと epilogue コードを生成しない

__attribute__((naked)) void Wait10Cycles(void){
   asm (
    /* bl to here: [4] */
   "nop   \n\t" /* [1] */
   "nop   \n\t" /* [1] */
   "nop   \n\t" /* [1] */
   "bx lr \n\t" /* [3] */
  );
}

ある場所で見かけた「何もせず待つ」という関数の中身を調べたところ↑のようになっていたので _attribute__((naked)) の意味について調べたことをメモしておきます。

参考 : Declaring Attributes of Functions
This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have prologue/epilogue sequences generated by the compiler. Only Basic asm statements can safely be included in naked functions (see Basic Asm). While using Extended asm or a mixture of Basic asm and “C” code may appear to work, they cannot be depended upon to work reliably and are not supported. 
まとめると
  • コンパイラに関数定義を作成させつつ、関数の中身は assembly コードで書ける
  • prologue コードと epilogue コードが生成されない
  • 関数内で安全に使用できるのは Basic asm のみ。拡張アセンブラ構文(Extended asm)や Cコードも動くように見えるかもしれないがサポートされていない。
今回の場合は、コンパイラが余計なコードを生成して意図したサイクル数からずれることがないよう naked をつけていたということですね。

Prologue コード(プロローグコード)とは

関数の先頭で、関数内で使用するスタックやレジスタの準備を行うコードのこと

Epilogue コード(エピローグコード)とは

関数の終わりで、スタックやレジスタを関数が呼ばれる前の状態に戻すコードのこと

Function prologue(英語版 Wikipedia へのリンク)

0 件のコメント:

コメントを投稿