Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为每个函数设置堆栈地址_C_Stack - Fatal编程技术网

C 为每个函数设置堆栈地址

C 为每个函数设置堆栈地址,c,stack,C,Stack,对于一个特殊的内存管理软件,我想指定每个函数堆栈的起始地址。它的功能应该非常类似于pthread\u attr\u setstackaddr,但不是设置每个线程的堆栈地址,而是设置每个函数的堆栈地址。例如,是否有函数/方法可以设置堆栈地址,如: SetFuncStack(main); int main(){ int a = 0; SetFuncStack(func1); func1(); int b = 10; SetFuncStack(func2); func2();

对于一个特殊的内存管理软件,我想指定每个函数堆栈的起始地址。它的功能应该非常类似于
pthread\u attr\u setstackaddr
,但不是设置每个线程的堆栈地址,而是设置每个函数的堆栈地址。例如,是否有函数/方法可以设置堆栈地址,如:

SetFuncStack(main);
int main(){
  int a = 0;
  SetFuncStack(func1);
  func1();
  int b = 10;
  SetFuncStack(func2);
  func2();
  return 0;
}
谢谢你的建议

更新:
因此,我愿意接受任何可能的技术,例如,如果我必须更改编译器或某些内核代码,我可以。我只是不知道该怎么做

这样的事情是可能的。对于CPU调度,我们使用
ucontext.h
库,它允许您访问上下文块来存储函数、堆栈和其他内容。您应该维护上下文块的RunQ。要添加到RunQ,请调用
allocate\u上下文(函数)带有:

void allocate_context(void (*function) (void)){
    ucontext_t* context = (ucontext_t*)malloc(sizeof(ucontext_t)); //allocate a context block
    int* stack = malloc(8192); //allocate a stack of 8192 bytes
    init_Context(Context, function, stack, sizeof(stack)); //call init_TCB
    AddQueue(RunQ, TCB); //call addQ to add this TCB into the "RunQ" 
}

    void init_Context (ucontext_t context, void (*function) (void), void *stackP, int stack_size){
    memset(context, '\0', sizeof(ucontext_t)); // wash, rinse
    getcontext(context); //get parent context
    context.uc_stack.ss_sp = stackP; 
    context.uc_stack.ss_size = (size_t) stack_size;
    makecontext(context, function, 0); // context is now cooked
}

我认为你做不到。堆栈只是从它当前所在的位置推送出来的。你可以为线程这样做,因为创建一个新线程需要为它创建一个新的堆栈,它可以位于任何位置。但是你不能在线程已经运行之后更改堆栈的位置,我的意思是,你完全可以通过编写自己的C编译器或者定制现有的C编译器来完成。否则你可能会走运。您可以编写一个包装函数来更改堆栈,然后调用作为参数传递的函数,然后修复堆栈——但您必须在汇编中完成。而且你不能在堆栈上传递函数参数……如果你提供了一个更大的上下文,理论上,你所要做的就是推送一个堆栈框架,使新的堆栈指针位于目标位置(我认为它被映射并保留用于此用途),也许有人会提出一个建议,即使该大小为“负”并环绕内存。因此,可以使用您正在使用的ABI的标准代码来实现这一点。(用于推动堆栈框架的标准汇编代码,即非C代码。)