一.实验原理
1.1系统调用的意义
(1)把用户从底层的硬件编程中解放出来
(2)极大的提高了系统的安全性
(3)使用户程序具有可移植性
1.2系统调用过程
(1)当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数。
(2)在Linux中是通过执行int $0x80来执行系统调用的,这条汇编指令产生向量为128的编程异常。
(3)Intel Pentium II中引入了sysenter指令。
1.3参数传递
(1)进程必须指明需要哪个系统调用,这需要传递一个名为 系统调用号的参数,使用eax寄存器传递系统调用号。
(2)每个参数的长度不能超过寄存器的长度,即32位。
(3)在系统调用号(eax)之外,参数的个数不能超过6个(ebx,ecx,edx,esi,edi,ebp)。
(4)如果参数超过6个,就将一个寄存器变成指针指向一块内存区域,区域中连续保存着参数。
1.4内嵌汇编语法
__asm__(
汇编语句模版:
输出部分:
输入部分:
破环描述部分);
二.实验过程
2.1调试课件上的例子程序,调用系统调用time(),"纯"C程序如下:
#include <stdio.h> #include <time.h> int main() { time_t tt; tt = time(NULL); struct tm *t; t = localtime(&tt); printf("time:%d-%d-%d %d:%d:%d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); return 0; }
2.2使用嵌入式汇编调用time系统函数,程序如下:
#include <stdio.h> #include <time.h> int main() { time_t tt; struct tm *t; asm volatile( "mov $0,%%ebx\n\t" //传递参数 "mov $0xd,%%eax\n\t"//传递系统调用号 "int $0x80\n\t" //触发128号中断 "mov %%eax,%0\n\t" //将返回值保存到天天变量中 :"=m"(tt) ); t = localtime(&tt); printf("time:%d-%d-%d %d:%d:%d\n",t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); return 0; }
2.3 自己选择系统调用,编程调用,我选择的是getuid,该函数返回用户的ID值,c语言程序如下:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int uid; uid =getuid(); printf("uid is %d\n",uid); return 0; }
结果如下所示:
2.4使用嵌入式汇编调用getuid,代码如下所示:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int main() { int uid; //uid =getuid(); asm volatile( "mov $0x18,%%eax\n\t"//传递系统调用号 "int $0x80\n\t" //触发128号中断 "mov %%eax,%0\n\t"//将结果保存到uid变量中 :"=m"(uid) ); printf("uid is %d\n",uid); return 0; }
三.实验总结
系统调用的工作机制
(1)传递参数包括函数参数和系统调用号
(2)触发int 0x80中断
(3)cpu切换到内核态执行系统函数
本次应该是第一次自己写程序,而不是照抄老师的,虽然还有些不太熟练,但也有了很大的进步,希望自己能坚持到底。加油!!!!!!!!!
lab4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
原文:http://www.cnblogs.com/crowpurple/p/5299539.html