从函数外部访问标签

Mik*_*las 7 c assembly kernel

代码:

/* ctsw.c : context switcher
 */

#include <kernel.h>

static void *kstack;
extern int set_evec(int, long);

/* contextswitch - saves kernel context, switches to proc */
enum proc_req contextswitch(struct proc_ctrl_blk *proc) {
  enum proc_req call;

  kprintf("switching to %d\n", getpid(proc));

  asm volatile("pushf\n"          // save kernel flags
               "pusha\n"          // save kernel regs
               "movl %%esp, %0\n" // save kernel %esp
               "movl %1, %%esp\n" // load proc %esp
               "popa\n"           // load proc regs (from proc stack)
               "iret"             // switch to proc
               : "=g" (kstack)
               : "g" (proc->esp)
               );

_entry_point:
  asm volatile("pusha\n"          // save proc regs
               "movl %%esp, %0\n" // save proc %esp
               "movl %2, %%esp\n" // restore kernel %esp
               "movl %%eax, %1\n" // grabs syscall from process
               "popa\n"           // restore kernel regs (from kstack)
               "popf"             // restore kernel flags
               : "=g" (proc->esp), "=g" (call)
               : "g" (kstack)
               );
  kprintf("back to the kernel!\n");

  return call;
}

void contextinit() {
  set_evec(49, (long)&&_entry_point);
}
Run Code Online (Sandbox Code Playgroud)

它是一个小型,协作,非抢占式内核的上下文切换器.使用要加载的进程的堆栈指针contextswitch()调用dispatcher().一旦加载了%esp和其他通用寄存器,iret就会调用它并且用户进程开始运行.

我需要设置一个中断返回点contextswitch()以后iret,所以我可以恢复内核上下文并返回系统调用到的值dispatcher().

如何_entry_point从函数外部访问内存地址?

Mik*_*las 3

在玩了一会儿 GCC 之后,我得到了答案。

下降到程序集会消除有关未使用标签的 GCC 警告。

所以,

_entry_point:
Run Code Online (Sandbox Code Playgroud)

被替换为

asm volatile("_entry_point:");
Run Code Online (Sandbox Code Playgroud)

void contextinit() {
  set_evec_(49, &&_entry_point);
}
Run Code Online (Sandbox Code Playgroud)

被替换为

void contextinit() {
  long x;
  asm("movl $_entry_point, %%eax\n"
      "movl %%eax, %0": "=g" (x) : : "%eax");
  set_evec(49, x);
}
Run Code Online (Sandbox Code Playgroud)