C,内联汇编 - mov指令段错误

时间:2016-05-11 10:15:30

标签: c segmentation-fault stack inline-assembly

我们正试图实施某种"纤维"并希望每一个"堆栈"在堆上分配,让我们说现在的固定大小接近2MB。

//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;
    ...
};

在创建光纤期间,我们会分配" stack"并将已创建的结构排入队列,以便以后在就绪队列中使用。

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)
        );

    ...
}

但是,该移动指令将导致段错误。为什么?我们怎么能绕过那个?

1 个答案:

答案 0 :(得分:1)

在i386上(内联汇编程序非常明显),堆栈会逐渐减少。这意味着朝向较低的地址,因此函数调用将减少堆栈地址。

这意味着当我们为线程/进程/等分配堆栈时。正常的做法是将堆栈指针寄存器指向已分配内存的末尾。

在你的情况下,这应该是:

f->esp = (reg_t)f->stack + FIB_STACK_SIZE;

我仍然不确定在C函数中使用内联汇编程序执行此操作是否是个好主意,而不是在汇编程序中完全编写函数,但这应解决当前问题。