李亚健 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、实验过程:
参考视频中的方式使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
1.根据实验指导按照过程,在实验楼环境下打开shell:
cd Code
cd shiyanlou_cs195
mkdir lab4 创建实验四文件夹
2.建立a.c:
touch a.c
vi a.c
其中我选取了系统调用号为4的write。其中,write有三个参数,第一个是表示写到终端屏幕上,1可以认为是屏幕的代号,第二个参数是写的内容,我是把hello world!写 到屏幕上,并换行,第三个参数是写入的字符串长度,长度要大于等于要输出的字符串长度,否则只能输出字符串的一部分
gcc a.c -o a
./a
3.建立a_asm.c对应于a.c嵌入汇编代码:
touch a_asm.c
vi a_asm.c
同理 gcc a_asm.c -o a_asm
./a_asm
与a.c结果一样。其中write系统调用有三个参数,分别是:写入的位置,内容和长度,所以转化为汇编对应的寄存器为eax(系统调用号为4),ebx(参数),ecx(输出位 置),edx(参数长度)
二、分析汇编代码调用系统调用的工作过程,特别是参数的传递的方式
1.write的系统调用号为4,将4赋给eax。
2.write有三个参数,第一个是屏幕的代号,将1赋给ebx,代表写入的位置。
3.第二个参数是写的内容,将ebx置为1.
4.第三个参数是写入的字符串长度,将d(13)赋给ecx。
5.然后int 0x80是中断,触发系统调用,就可以调用write了。
6.最后一句movl %%eax,%0\n\t可以理解为恢复破坏部分。
7.然后其中%0代表a,%1代表输出ch。得到ch指向的字符串,打印hello world!。
三、对“系统调用的工作机制”的理解。
1.任何计算机相关问题都可以通过加一个中间层来解决。操作系统的系统调用也是这样,system_call将api和系统函数连接起来,这样可以保证内核的安全,不会因为用户的失误操作而造成问题。操作系统为了安全,把一些重要的调用放在内核部分,这样只能通过触发系统调用来完成相应功能,这样可以保证内核的安全,但是不可避免的也造成了系统调用的消耗比较大,因为有中断,传参,保存数据和恢复数据的过程。因此,如非必要的话,不建议使用系统调用。
2.系统调用的过程,可以先是用户通过API,产生中断,然后传参调用不同种类的服务程序。系统调用需要输入输出参数,一般通过ebx、ecx等寄存器传值。当参数个数大于6个时,可以用某个寄存器指向某个内存,然后利用那一块内存空间来进行值传递。