内容说明
本次的内容,是一次 MOOC 课程的作业。具体的,是使用汇编对 Linux 系统调用部分进行模拟实现,从而更加直观的验证 Linux 系统的基本机制。作业声明
qianyizhou17 + 原创作品转载请注明出处 + 《Linux 内核分析》MOOC 课程 http://mooc.study.163.com/course/USTC-1000029000实验准备
1 本次实验并没有使用 MOOC 课程上提供的实验楼的环境,而是自行搭建了 64Bit Ubuntu 虚拟机。
2 MAC 端的虚拟机使用 VMware 还是有些不够好用,又转回了 parallel,终于共享目录和复制/粘贴都好用了。
3 本次试验使用了 Ubuntu 16.04,环境搭建和软件安装部分,可以参照上一篇博客的环境搭建部分。实验操作
1 按照要求,从系统调用号列表中,选取getpid 进行试验。该 API 对应的系统调用号为 0x1D。该函数没有入参,仅使用 eax 传递系统调用号 0x1D 即可,系统调用的返回值仍然使用 eax 传出。
2 代码准备
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
/*
* normal system call
*/
pid_t pid_get = getpid();
printf( "pid: %d\n", pid_get );
/*
* asm system call
*/
pid_t pid_asm;
asm volatile (
"mov $0, %%ebx\n\t"
"mov $0x14, %%eax\n\t"
"int $0x80\n\t"
"mov %%eax, %0\n\t"
: "=m" (pid_asm)
);
printf( "pid_asm: %d\n", pid_asm );
return 0;
}
3 编译
$ gcc getpid.c -Wall -m32 -o get_pid
4 执行与输出结构
$./get_pid
pid: 14819
pid_asm: 14819
- 总结
1 Linux 系统分为用户态和内核态,而中断响应,便是用户态进入内核态的一种常见方式
2 系统调用便是一种特殊的中断
3 用户空间进行系统调用时:
1)进行系统调用(getpid)时,首先会触发一个中断向量号为 0x80 的系统中断
2)该中断对应的中断处理函数便是 system_call,从而进入了内核态
3)通过寄存器传递的系统调用号——即对应了本例中的 0x14,进一步定位到了 system_call 下的中断服务程序 sys_getpid
4)逐层返回,从而完成系统调用,并返回结果(通过 eax)