简体   繁体   English

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

[英]C,inline assembly - mov instruction segfaults

We're trying to implement some kind of "fibers" and want for each a "stack" allocated on the heap, let's say of fixed size somewhere near 2MB, for now. 我们正在尝试实现某种“光纤”,并且现在希望为每个分配在堆上的“堆栈”,比如说固定大小约为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;
    ...
};

During creation of a fiber, we allocate that "stack" and enqueue the created struct for later use in a ready queue. 在创建光纤的过程中,我们分配该“堆栈”,并将创建的结构排队,以供以后在就绪队列中使用。

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 is the struct taken from the ready queue for which we need to restore the context. fib是从就绪队列中获取的结构,我们需要为其还原上下文。

Obviously, we first need to restore the stack pointer s.th. 显然,我们首先需要恢复堆栈指针s.th。 we can restore everything else: 我们可以还原其他所有内容:

void fib_resume(){
    //assumes `fib' holds fiber to resume execution

    //restore stack pointers
    __asm__(
        "movl %0, %%esp;"
        :
        :"rm"(fib->esp)
        );

    ...
}

However, that move instruction will result in a segfault. 但是,该移动指令将导致段错误。 Why? 为什么? And how can we circumvent that? 而我们该如何规避呢?

On i386 (which is pretty apparent from the inline assembler) the stack grows down. 在i386上(从内联汇编程序可以很明显地看出),堆栈逐渐变小。 That means towards lower addresses, so function calls will decrement the stack address. 这意味着将地址移到较低的地址,因此函数调用将减少堆栈地址。

This means that when we're allocating a stack for a thread/process/etc. 这意味着当我们为线程/进程/等分配堆栈时。 the normal way of doing it is to point the stack pointer register at the end of the allocated memory. 通常的做法是将堆栈指针寄存器指向已分配内存的末尾。

In your case this should be: 在您的情况下,应为:

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

I'm still not sure if it's a good idea to do this with inline assembler in a C function rather than writing the function completely in assembler, but this should resolve the immediate problem. 我仍然不确定在C函数中使用内联汇编程序来执行此操作,而不是在汇编器中完全编写该功能,这是否是一个好主意,但这应该可以解决当前的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM