2017-04-21 4 views
0

私はboost fcontextの実装を読んでいます。ブーストコンテキストの実装

make_fcontextの関数プロトタイプが typedef void* fcontext_t; fcontext_t BOOST_CONTEXT_CALLDECL make_fcontext(void * sp, std::size_t size, void (* fn)(intptr_t));

最初の引数は、コンテキストスタックの最上位である次のように、ブーストドキュメントからの例は次のとおりです。

私はの実装を読んでいる
// context-function 
void f(intptr); 


// creates a new stack 
std::size_t size = 8192; 
void* sp(std::malloc(size)); 

// context fc uses f() as context function 
// fcontext_t is placed on top of context stack 
// a pointer to fcontext_t is returned 
fcontext_t fc(make_fcontext(sp,size,f)); 

i386_elfのmake_contextでは、実装が常にspを減らし、mallocからメモリが足りないspの前にメモリにコンテキストストアを作成します。コルーチンに属していないmemroyを上書きできますか?

/* first arg of make_fcontext() == top of context-stack */ 
movl 0x4(%esp), %eax 

/*decrease the adress of sp here*/ 
/* reserve space for first argument of context-function 
    rax might already point to a 16byte border */ 
leal -0x8(%eax), %eax 

/* shift address in EAX to lower 16 byte boundary */ 
andl $-16, %eax 

/* reserve space for context-data on context-stack */ 
/* size for fc_mxcsr .. EIP + return-address for context-function */ 
/* on context-function entry: (ESP -0x4) % 8 == 0 */ 
leal -0x20(%eax), %eax 

/* third arg of make_fcontext() == address of context-function */ 
movl 0xc(%esp), %edx 
movl %edx, 0x18(%eax) 

/* save MMX control- and status-word */ 
stmxcsr (%eax) 
/* save x87 control-word */ 
fnstcw 0x4(%eax) 
+1

ブーストは、C++クラスライブラリではなく、Cライブラリです。それに応じてタグを更新することもできます。 – Gerhardh

+0

思い出していただきありがとうございます。 – Jayce

答えて

2

あなたのCPUのアーキテクチャに応じて、スタックは下向き(上位アドレスに向かって)上向き(x86の上の場合のように、下位アドレスに向けて)を育てることがあります。これは、一般に、pushおよびpop命令がスタックポインタを変更する方法によって命令セット内でハードにコード化される。たとえば、x86 push命令は[er]?spから減算されます。

make_fcontextは、プラットフォームが必要とするアーキテクチャー固有の方向に十分なスペースを持つことを期待しています。 x86では、の前にポインタがより前に空き領域がなければなりません。あなたが受け取ったポインタをmallocから直接渡すことによって、あなたはこの契約に違反しています。

これは、stack_allocatorの抽象概念が存在する理由です。それらは、アーキテクチャに応じてスタックの右端を指すポインタを返します。

(注意点として、私は現在Boost.Contextでサポートされているすべてのアーキテクチャは下向きに成長するスタックを持っていると信じています。)