实验部分
根据系统调用表,选取一个系统调用。我选得是mkdir这个系统调用,其系统调用号为39,即0x27
-
由于mkdir函数的原型为
int mkdir (const char *filename, mode_t mode)所以根据其原型编写一下代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
const char *ch = "test"; //创建的文件夹名称
mode_t mode = 0700; //创建的文件夹的权限
int flag = 0; //是否创建成功新的文件夹的标识符
flag = mkdir(ch,mode); //调用mkdir
if(flag==0) //flag=0则创建成功,否则失败
{
printf("succeed");
}
else
printf("error");
return 0;
}
mkdir.c的运行结果如下:
当运行完mkdir可执行文件时,产生了新的文件夹test。
-
改编成会变代码调用
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{
char *ch="test-asm"; //创建文件夹的名称
mode_t mode=S_IRWXU; //创建新的文件夹的权限
int flag=0; //标识符
asm volatile(
"mov $0x27,%%eax\n\t" //系统调用号赋给eax寄存器
"mov %1,%%ebx\n\t" //将文件夹的名称赋给ebx寄存器
"mov %2,%%ecx\n\t" //将文件夹的权限赋给ecx寄存器
"int $0x80\n\t" //开启中断,执行mkdir系统调用
"mov %%eax,%0\n\t" //将返回值赋给flag
:"=m"(flag) //输出变量flag
:"d"(ch),"D"(mode) //输入变量ch与mode
);
if(flag==0) //flag=0则创建成功,否则失败
printf("succeed");
else
printf("error");
return 0;
}
结果如下图:
总结
1.系统调用的三层皮:xyz system_call sys_xyz
对应的是API,中断向量对应的中断服务程序,系统调用服务程序。
API:应用编程接口
它与系统调用的关系:API可能直接提供用户态的服务,不是一个API都有与之相对应的系统调用。
2.中断处理,用户态及内核态
通过cs:eip的值判断代码段是在用户态还是内核态
中断处理是一种由用户态进入内核态的方式(系统调用也可以理解为是一种中断)
中断发生后,首先要保存现场
3.系统调用简单点说,就是通过设置输入输出变量,令其存在于ebx等寄存器中,而后将系统调用号赋给eax寄存器,最后通过int 0x80来进行中断,从而开始所选择的系统调用。
若有返回值,则将返回值传至eax寄存器中,我们便可以利用返回值来给出一定的结论(如操作成功或失败)。
注:
姓名:林涵锦
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000