2011-11-25 9 views
8

2つのマクロがあり、1つはアセンブリで、もう1つはCで書かれています。しかし、私はまた、volatileでアセンブリに2番目のマクロを書きたいので、私はコード内の配置を制御することができます。 tidは実行時の値であり、nのような定数ではありません。アセンブリでこれをすべて書くにはどうすればいいですか?

これをアセンブリに書くにはどうすればよいでしょうか?また、volatileのアセンブリのようなCコードの配置を制御することは可能ですか?

#define SAVE_SP(n) __asm__ __volatile__ ("movq %rsp, msp"#n";" \ 
    "movq ts"#n", %rsp;" \ 
    ) 

#define SAVE_STACK_POINTER(tid) \ 
    switch(tid) \ 
    { \ 
     case 0: \ 
      SAVE_SP(0); \ 
      break; \ 
     case 1: \ 
      SAVE_SP(1); \ 
      break; \ 
     case 2: \ 
      SAVE_SP(2); \ 
      break; \ 
     case 3: \ 
      SAVE_SP(3); \ 
      break; \ 
    } 
+0

tidは実行時の値であり、nのような定数ではありません。 – MetallicPriest

+0

(気にしていない、ナイスセンスでした) –

+1

'tsp 'と 'msp 'の値を配列に格納することはできますか? –

答えて

6

あなたはアセンブリでコードを書く方法のその考えをgccの尋ねることができます。gcc -S foo.cgcc -Wa,-alh=foo.s -c foo.c。もちろん、結果を改善したいかもしれません。あなたは少し余分にする必要があります:アセンブリのチャンクに渡すパラメータのために%0を使用し、clobberedしたレジスタを宣言してください。おなじみでない場合は、Assembler Instructions with C Expression Operands in the GCC manualを参照してください。これはどのように見えるか(警告、直接ブラウザに入力され、実際にはx86アセンブリ構文はわかりません)。

#define SAVE_STACK_POINTER(tid) __asm__ __volatile__ (" \ 
     cmpl $0, %0         \n\ 
     je .SAVE_STACK_POINTER_0      \n\ 
     cmpl $1, %0         \n\ 
     je .SAVE_STACK_POINTER_1      \n\ 
     cmpl $2, %0         \n\ 
     je .SAVE_STACK_POINTER_2      \n\ 
     cmpl $3, %0         \n\ 
     je .SAVE_STACK_POINTER_3      \n\ 
     jmp .SAVE_STACK_POINTER_done     \n\ 
     .SAVE_STACK_POINTER_0:       \n\ 
     movq %%rsp, msp0        \n\ 
     movq ts0, %%rsp        \n\ 
     jmp SAVE_STACK_POINTER_done     \n\ 
     .SAVE_STACK_POINTER_1:       \n\ 
     movq %%rsp, msp1        \n\ 
     movq ts1, %%rsp        \n\ 
     jmp SAVE_STACK_POINTER_done     \n\ 
     .SAVE_STACK_POINTER_2:       \n\ 
     movq %%rsp, msp2        \n\ 
     movq ts2, %%rsp        \n\ 
     jmp SAVE_STACK_POINTER_done     \n\ 
     .SAVE_STACK_POINTER_3:       \n\ 
     movq %%rsp, msp3        \n\ 
     movq ts3, %%rsp        \n\ 
     .SAVE_STACK_POINTER_done:      \n\ 
    " : : "r" (tid)) 

movqどのように多くのバイトを考え出す伴うだろう手の込んだ方法 - movqからjmpブロックが取りを(注:私はチェックしていない、私は8を使用)と、それに計算されたジャンプを作ります。

static register int stack_pointer0 asm("msp0"); 

void myfn() { 
    ...... 
    saved_stack_pointer = stack_pointer0; 
    ...... 
} 

OK、おそらく行いません:あなたはGCCを使用していると仮定すると、

__asm__("      \n\ 
    movl %0, %eax    \n\ 
    mul 8, %eax     \n\ 
    add 4, %eax     \n\ 
    jmp . + %eax     \n\ 
    movq %%rsp, msp0    \n\ 
    movq ts0, %%rsp    \n\ 
    jmp .SAVE_STACK_POINTER_done \n\ 
    … 
    .SAVE_STACK_POINTER_done:  \n\ 
" : : "r" (tid) : "%eax") 
1

のようなものは、あなたがC変数にスタック・ポインタ・レジスタをマッピングするためにGNUの拡張機能を使用することを試みることができます元のコードが何をしたのか(それは私には目標が何であるかは分かりませんでしたが)残りの部分を把握できるはずです。

私は構文が正しいと思いますが、そうでなければ謝ります。私はこれが一般的なレジスタのために働くことを知っています、そして、私はGCCが特別なレジスタのために何をすべきかを知っていますが、あなたは決して知りません。

希望に役立ちます。

関連する問題