lcall(调用门)和0x80(中断门)触发系统调用区别

你想要用“手动中断(int 指令)”的方式触发系统调用,而不是用 lcall(调用门),这是完全可行的,而且在早期 Linux(如 int 0x80)中就是这么做的。

下面是你实现这类机制所需要的完整步骤,包括用户态和内核态的设计。


✅ 一、用户态:使用 int 指令触发中断

你可以写一个系统调用封装函数,比如:

static inline int sys_call(syscall_args_t *args) {
    int ret;
    __asm__ __volatile__ (
        "int $0x80\n"
        : "=a"(ret)
        : "a"(args)
        : "memory"
    );
    return ret;
}

📌 说明:

  • int $0x80:触发中断向量 0x80;
  • args(系统调用参数结构体地址)通过 eax 寄存器传给内核;
  • 返回值也通过 eax 返回。

✅ 二、内核态:中断向量 0x80 的处理逻辑

你需要设置 IDT 的 0x80 向量指向你自己的系统调用处理函数:

set_idt_gate(0x80, exception_handler_syscall, DPL_USER);

确保这个中断门设置的是:

  • 权限允许用户态触发(DPL=3);
  • 目标函数是 exception_handler_syscall
  • 类型为中断门或陷阱门。

✅ 三、异常处理入口:exception_handler_syscall

这段逻辑可以和你之前的调用门逻辑共用:

exception_handler_syscall:
    pusha
    push %ds
    push %es
    push %fs
    push %gs
    pushf

    mov $(KERNEL_SELECTOR_DS), %eax
    mov %eax, %ds
    mov %eax, %es
    mov %eax, %fs
    mov %eax, %gs

    mov %esp, %eax         ; 当前内核栈
    push %eax
    call do_handler_syscall
    add $4, %esp

    popf
    pop %gs
    pop %fs
    pop %es
    pop %ds
    popa
    iret

✅ 四、系统调用处理函数:do_handler_syscall

void do_handler_syscall(trapframe_t *tf) {
    syscall_args_t *args = (syscall_args_t *)(tf->eax);  // 从 eax 中取参数
    int result = syscall_dispatch(args->id, args->arg0, args->arg1, args->arg2, args->arg3);
    tf->eax = result; // 将结果返回给用户态(iret 后生效)
}

🔁 用户态回到原处

中断返回使用 iret,CPU 会自动恢复 CS/EIP/EFLAGS,回到用户态的 int 0x80 之后的指令,用户态函数 sys_call() 获取返回值,结束。


✅ 总结:你需要改哪些地方?

位置原 lcall 方式新 int 方式
用户态调用lcalll *(%[gate])int $0x80
参数传递压栈eax 寄存器(可扩展用其他寄存器)
内核入口调用门目标函数IDT 中断向量 0x80
权限设置GDT 调用门 DPL=3IDT 中断门 DPL=3
返回方式lretiret

❗️进阶建议

你还可以将多个参数放到寄存器里(比如 eax、ebx、ecx、edx 等),模仿 Linux 的做法(int 0x80 调用约定),不用结构体传参。

如果你想我帮你设计一个更轻量的 int 调用 + 寄存器传参 + dispatch 表实现,我也可以写一个模板给你。要试试看吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值