C语言中的参数传递和堆栈设置

时间:2015-11-05 07:22:21

标签: c stack parameter-passing page-fault

我目前正在尝试在我的操作系统课程中为部分项目实现参数传递。我们需要解析和标记化文件名,并存储(使用memcpy)参数的值,参数的指针以及一些其他的各种格式化功能。

它必须遵循此图所示的格式(示例命令为/ bin / ls -l foo bar):enter image description here

这是我的解决方案。目前,它导致页面错误,这表明参数传递不按预期工作。

static bool
setup_stack (void **esp, const char* file_name)
{
  uint8_t *kpage;
  bool success = false;

  kpage = palloc_get_page (PAL_USER | PAL_ZERO);
  if (kpage != NULL)
    {
      success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true);
      if (success)
        *esp = PHYS_BASE;
      else
        palloc_free_page (kpage);
        return success;
    }

  /* Our code starts here */

  int i = 0;
  int argc = get_argc(file_name);
  char *token, *save_ptr;
  char **argv = malloc((argc + 1) * sizeof(char *));
  size_t token_size;

  //generate argv and push args onto stack
  for (token = strtok_r((char *)file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)) {
    token_size = strlen(token) + 1;
    *esp = *esp - token_size;
    argv[i] = *esp;
    i++;
    memcpy(*esp, token, token_size);
  } argv[argc] = 0;

 //perform alignment
  size_t alignment = (size_t) *esp % 4;
  if (alignment) {
    *esp = *esp - alignment;
    memcpy(*esp, &argv[argc], alignment);
  }

  //push argv pointers
  for (i = argc; i >= 0; i--) {
    *esp = *esp - sizeof(char *);
    memcpy(*esp, &argv[i], sizeof(char *));
  }

  //push pointer to argv
  ptr = *esp;
  *esp = *esp - sizeof(char *);
  memcpy(*esp, &ptr, sizeof(char *));

  //push argc
  *esp = *esp - sizeof(int);
  memcpy(*esp, &argc, sizeof(int));

  //push dummy return address
  *esp = *esp - sizeof(void *);
  memcpy(*esp, &argv[argc], sizeof(void *));

  free(argv);

  return success;
}

我写的辅助函数叫做get_argc():

/* Return the number of tokens given a command 'file_name.' */
int get_argc(const char* file_name) {
    int argc = 0;
    char *buffer, *token, *save_ptr;
    buffer = malloc(sizeof(file_name));
    strlcpy(buffer, file_name, sizeof(file_name));
    for (token = strtok_r((char *)buffer, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)) {
        argc++;
    }
    free(buffer);
    return argc;
}

提前感谢任何看过这个的人。 编辑:代码格式

0 个答案:

没有答案