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

李亚健    《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个时,可以用某个寄存器指向某个内存,然后利用那一块内存空间来进行值传递。

posted @ 2017-03-17 21:39  somnus赤系  阅读(303)  评论(0编辑  收藏  举报