《Linux内核分析》 第四节 扒开系统调用的三层皮(上)

本文详细介绍了系统调用的三层皮模型、API与中断处理机制,通过fork系统调用实例展示了如何使用库函数API和C代码中的汇编方式调用系统调用,并分析了参数传递过程。实验结果通过截图呈现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

黄胤凯   原创作品转载请注明出处   《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

一、视频学习

1.系统调用的三层皮:xyz    system_call    sys_xyz

对应的是API,中断向量对应的中断服务程序,系统调用服务程序。

 

API:应用编程接口            

它与系统调用的关系:API可能直接提供用户态的服务,不是一个API都有与之相对应的系统调用。

 

2.中断处理,用户态及内核态

通过cs:eip的值判断代码段是在用户态还是内核态

中断处理是一种由用户态进入内核态的方式(系统调用也可以理解为是一种中断)

中断发生后,首先要保存现场,将数值压栈,保存到相应的寄存器中,然后响应中断,将数值弹栈,恢复现场。

 

 

二、使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

  • 实验报告

  • 选择一个系统调用(13号系统调用time除外),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl 参考视频中的方式使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

  • 博客内容的具体要求如下:

    1. 题目自拟,内容围绕系统调用的工作机制进行,博客中需要使用实验截图

    2. 博客内容中需要仔细分析汇编代码调用系统调用的工作过程,特别是参数的传递的方式等。

    3. 总结部分需要阐明自己对“系统调用的工作机制”的理解。

 

  • 本次实验选择了2号调用fork调用来做实验:fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID

用实验楼的虚拟机打开shell

Cd Code
Vi forktest.c
Gcc forktest.c -o forktest.o -m32
./forktest.o

fork.c代码如下

复制代码
#include <unistd.h>
#include <stdio.h>
int main ()
{
    pid_t fpid;
    int count = 0;
    fpid = fork();
    if (fpid < 0)
        printf("error in fork!");
    else if (fpid == 0) {
        printf("i am the child process, my process id is %d\n",getpid());
        count++;
    }
    else {
        printf("i am the parent process, my process id is %d\n",getpid());
        count++;
    }
    printf("count: %d\n",count);
    return 0;
}
复制代码

 

 运行结果见截图 

  • 嵌入式汇编代码的执行,fork-asm.c源代码如下(参数的传递方式见注释):

 

复制代码
#include <unistd.h>
#include <stdio.h>
int main ()
{
    pid_t fpid;
    int count = 0;


asm volatile (
            "mov $0, %%ebx\n\t"       
            "mov $0x2, %%eax\n\t"    // 将fork的系统调用号0x2赋值给eax
            "int $0x80\n\t"          // 通过0x80中断向量,执行系统调用
            "mov %%eax, %0\n\t"      // 系统返回的pid号默认储存在eax中
            : "=m" (fpid)            // 输出操作数0为内存中的fpid。
            );
if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am the child process, my process id is %d\n",getpid()); count++; } else { printf("i am the parent process, my process id is %d\n",getpid()); count++; } printf("count: %d\n",count); return 0; }
复制代码

运行结果见截图

 

转载于:https://www.cnblogs.com/20132109HKK/p/5295680.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值