あなたはアセンブリでコードを書く方法のその考えをgccの尋ねることができます。gcc -S foo.c
かgcc -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")
tidは実行時の値であり、nのような定数ではありません。 – MetallicPriest
(気にしていない、ナイスセンスでした) –
'tsp'と 'msp 'の値を配列に格納することはできますか? –