私たちはある種の "ファイバー"を実装しようとしており、ヒープ上に割り当てられたそれぞれの "スタック"を必要としています。C、インラインアセンブリー - mov命令segfaults
//2MB ~ 2^21 B = 2097152 B
#define FIB_STACK_SIZE 2097152
#define reg_t uint32_t
typedef struct fiber fiber;
struct fiber{
...
//fiber's stack
reg_t esp;
...
};
ファイバーの作成中に、私たちはその「スタック」を割り振り、作成した構造体を後でレディキューで使用できるようにエンキューします。
void fib_create(...){
//fiber struct itself
f = malloc(sizeof(*f)); //f later enqueued
...
//fiber stack
f->stack = malloc(FIB_STACK_SIZE);
f->esp = (reg_t)f->stack;
...
}
fib
たちは、コンテキストを復元する必要があるため、レディキューから取り出した構造体です。明らかに、最初にスタックポインタs.thを復元する必要があります。
void fib_resume(){
//assumes `fib' holds fiber to resume execution
//restore stack pointers
__asm__(
"movl %0, %%esp;"
:
:"rm"(fib->esp)
);
...
}
ただし、その移動命令はsegfaultになります。どうして?それをどう回避することができますか?
[mcve]を作成する必要があります。 – user694733
http://stackoverflow.com/questions/19392336/gcc-inline-assembly-wont-let-me-overwrite-esp – stark
おそらく、segfaultを引き起こすのは「mov」ではないでしょう。これは 'fib_resume'からの戻り値です。 'fib_resume'関数が動作するためにスタックに十分な情報が含まれていますか?コンパイルされたCコードがスタック上にあると予想していることを知るのはかなり難しいので、ほとんどすべてのオペレーティングシステムはアセンブラでコンテキストの切り替えを行います。 – Art