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

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


本周我们的实验是“使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用”,系统调用列表列出了x86-32下的系统调用名称及中断号的对应关系。


我们在本试验中选用了文件读写相关的系统调用,包括打开文件open(系统调用号5),关闭文件close(系统调用号6),读文件read(系统调用号3),以及写文件write(系统调用号4)。我们用这四个函数实现了一个文件拷贝的过程,该文件从Linux/Unix系统编程手册[0]中的示例代码修改而来。

程序原理是打开准备拷贝的文件,同时创建一个新文件,循环从源文件中读取数据,写入到新文件中,读写完成后关闭两个文件。

首先我们用库函数来使用系统调用:



我们编译并测试一下该程序:



可以看出来,我们用copy复制syscall.txt到res.txt,然后用diff命令检测了两个文件的一致性,测试证明该程序运行正常。

接下来我们利用C代码嵌入汇编来使用系统调用,我们这里实现了库函数的相应版本,以函数前加下划线来指明我们自己写的封装。我们先看一下库函数的接口,便于我们直接模仿:

<span style="font-size:14px;">       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);
       int close(int fd);
       ssize_t write(int fd, const void *buf, size_t count);</span>

这些函数的定义我们可以在man page中找到


我们用汇编语言重写的函数如下:

open:因为该函数由两种参数列表,所以我们将其写成两个函数,最后我们会说明如何将其写成同名函数,即实现所谓的"重载"。(注意,这里所说的重载只是意义上的,并不是C++中的重载概念)。


"重载"open


write and read


close:



main函数:我们在这里封装了汇编函数,所以main函数和调用C库的main完全一样,只是替换了相应函数名(前面加下划线)



这个过程十分简单,只需要将参数装入相应的寄存器,向eax中传递系统调用号,然后执行int 0x80进入系统调用即可,待调用完成后,我们从eax中读取返回值。
这里面有几个问题需要注意:

0. 寄存器的使用如下表所示

Syscall # Param 1 Param 2 Param 3 Param 4 Param 5 Param 6
eax ebx ecx edx esi edi ebp
Return value
eax
1. C嵌入汇编的语法告诉我们,只要我们指明输入参数存放的寄存器,如"b" (fd), "c" (buf), "d" (count) 编译器就会帮助我们自动在该代码段执行前将参数放入相应的寄存器。所以这里我们不需要在mov参数到相应的寄存器中。
2. 这里的参数顺序和库函数的参数顺序是一致的,并不是相反顺序,之前一直认为应该以相反的顺序存放参数,导致程序一直错误,查到了相关资料后[1],修改顺序,程序运行正确。
3. 关于open函数,我们在man page中可以看到,该函数由两种形式,好像重载了一样,经过查阅资料,发现可以用va_args来实现该功能。关于这一点,可以参见 这里[2]。


最后,我们来编译并测试一下汇编版本的程序:


这一节我们就分享到这里,希望对读者有所帮助。


参考资料:

[0]. Linux/UNIX系统编程手册

[1]. Professional assembly language

[2]. 如何实现 C 的函数重载


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值