Linux 系统调用初探(一)

原创作品转载请注明出处,《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

1、使用系统函数实现scanf() 和 printf()

 很明显,上述代码从标准输入设备读取一段字符串,然后打印出来。

编译运行:

图1.代码运行截图

2、使用系统中断实现scanf() 和 printf()

先查询得到如下linux系统中断:

 代码如下:

编译运行:

2图2.代码运行截图2

注意:

  • 数组名和字符串指针的差别。可能大家在C语言层面对二者相当熟悉,但是到了汇编语言的层面,问题变得更直接了。
  • 数组名作为一个常量指针,数组名的地址就是数组第一个元素所在的地址;字符串指针是一个变量,该指针的地址随机,在其地址位置保存了对应字符串地址。所以在将参数传递给write()系统调用的时候,

lea [数组名] %ecx 表示将数组名所在的“内存地址”装入%ecx寄存器中

mov [字符串指针] %ecx 表示将该字符串指针指向的内存地址处所保存的“值”保存到 %eax寄存器中

  • linux系统中,每个进程的进程描述符中有一个数组专门用来记录该进程所打开的文件描述符。默认情况下,0、1分别表示标准输入和标准输出,2表示标准错误输出。所以上述代码中,我直接使用了立即数0、1这样的数字填充了 %ebx寄存器,作为传递给write()调用的第一个参数(文件描述符)

3、作业小结

        包括linux在内的众多操作系统中,操作系统为我们提供了大量的软中断以实现和硬件的直接通讯,而有了高级语言的支持之后,系统中断被封装成大量的系统API或者说是库函数,极大地方便了开发者的开发工作。使开发者能够脱离具体的硬件细节,将注意力集中于算法和应用层面。

        但是我们作为计算机专业的学生,对于底层实现必须有清楚的认识,我们不能被华丽的系统库函数所蒙蔽,应该深入底层,挖掘最有价值的代码。

发表评论

电子邮件地址不会被公开。 必填项已用*标注