简体   繁体   English

在xv6中创建线程时注册指针

[英]Register pointer in creating threads in xv6

I want to create a thread in xv6 by using a system call "clone()", but I am confused about the stack creation, since if I want to create a thread, I need to create the corresponding register pointer such like ebp, esp, eip. 我想使用系统调用“ clone()”在xv6中创建线程,但是我对堆栈的创建感到困惑,因为如果我要创建线程,则需要创建相应的寄存器指针,例如ebp,esp ,eip。 But I don't know how to set the value of these register pointer. 但是我不知道如何设置这些寄存器指针的值。

Here is a code of clone() in xv6, I don't know why we need to set the value of the register pointer like this....... 这是xv6中的clone()代码,我不知道为什么我们需要像这样设置寄存器指针的值。

int clone(void(*fcn)(void*), void *arg, void*stack){

  int i, pid;
  struct proc *np;
  int *ustack = stack + PGSIZE - sizeof(void*);
  //allocate process.
  if((np=allocproc()) == 0)
    return -1;

  //copy process state from p
  np->pgdir = proc->pgdir;
  np->sz = proc->sz;
  np->parent = 0;
  np->pthread = proc;
  *np->tf = *proc->tf;
  np->ustack = stack;

  //initialize stack variables 
  //void *stackArg, *stackRet;
  //stackRet = stack + PGSIZE -2*sizeof(void*);
  //*(uint *)stackRet = 0xffffffff;

  //stackArg = stack + PGSIZE -sizeof(void*);
  //*(uint *)stackArg = (uint)arg;
  *ustack = (int) arg;
  *(ustack - 1) = 0xffffffff;
  *(ustack - 2) = 0xffffffff;


  //Set stack pinter register
  np->tf->eax = 0;
  np->tf->esp = (int) ustack - sizeof(void*);
  np->tf->ebp = np->tf->esp;
  np->tf->eip = (int)fcn;

  for(i = 0; i < NOFILE; i++) {
    if(proc->ofile[i])
      np->ofile[i] = filedup(proc->ofile[i]);
  }

  np->cwd = idup(proc->cwd);
  np->state = RUNNABLE;
  safestrcpy(np->name, proc->name, sizeof(proc->name));
  pid = np->pid;
  return pid;

}

You don't set these registers -- clone sets them for you. 您无需设置这些寄存器-克隆将为您设置它们。 You need to provide a function (which clone uses to initialize ip) and a stack (which clone uses to initialize sp). 您需要提供一个函数(该克隆用于初始化ip)和一个堆栈(该克隆用于初始化sp)。

The function pointer is pretty straight-forward (its just a C function pointer), but the stack is trickier. 函数指针很简单(它只是一个C函数指针),但是堆栈比较棘手。 For the clone implementation you show, you need to allocate some memory and provide a pointer PGSIZE below the end of that block. 对于clone告诉你执行,你需要分配一些内存,并提供一个指针PGSIZE该块的端部下方。 Linux's clone call is similar, but slightly different (you need to provide a pointer to the end of the block). Linux的克隆调用类似,但略有不同(您需要提供一个指向块末尾的指针)。 If you want to catch stack overflows, you'll need to do more work (probably allocating a read/write protected guard page below the stack). 如果要捕获堆栈溢出,则需要做更多的工作(可能在堆栈下方分配一个受读/写保护的保护页)。

Of all the register values you set, the only useful ones are: 在您设置的所有寄存器值中,唯一有用的是:

eip - Tells the thread where to start executing from when it returns to userspace eip-告诉线程从返回用户空间时开始在哪里执行

esp - This is points to the top of the stack. esp-这指向堆栈的顶部。 This means that if you did this right, 4 bytes stored at the top of the stack should contain your return address 这意味着,如果您正确执行此操作,则存储在堆栈顶部的4个字节应包含您的返回地址


eax is not really useful here seeing as the thread jumps to a new context and not the one where it was created. 当线程跳转到一个新的上下文而不是创建它的地方时, eax在这里并不是真正有用的。 Otherwise, eax will store the return value of the last system call. 否则, eax将存储上一个系统调用的返回值。 See the implementation of fork if you are still confused about this one. 如果您仍然对此感到困惑,请参阅fork的实现。

ebp is not manipulated by you, but rather by the x86 function call conventions and is usually set to the value of esp when the function is called. ebp不是由您操纵的,而是由x86函数调用约定来操纵的,通常在调用函数时将其设置为esp的值。 As such you will usually see this sort of thing in the disassembly of most function calls 这样,您通常会在大多数函数调用的反汇编中看到这种情况

push ebp      ; Preserve current frame pointer
mov ebp, esp  ; Create new frame pointer pointing to current stack top

ebp is also useful for stack tracing because it stores the top of the previous function's stack before it is then changed to point to the current stack top ebp对于堆栈跟踪也很有用,因为它存储前一个函数堆栈的顶部,然后再将其更改为指向当前堆栈顶部


You don't need this *(ustack - 2) = 0xffffffff; 您不需要这个*(ustack - 2) = 0xffffffff;

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

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