1.引言

正式开始之前,每个人心里都应该有一点逼数,就像下面这张图一样。

系统调用也是函数调用,系统函数也是函数代码。系统函数与普通函数唯一的不同在于,系统函数可以使用cpu体系结构指令集中的特权指令,如启动I/O设备指令、修改某些个特殊寄存器的指令,如程序状态寄存器PSW。既然系统调用也是函数调用,那么就要遵守函数调用的基本法。1.传参 2.调用 3.返回。在汇编代码中,在正式call一个函数之前,需要将相关寄存器的值设置好,然后再修改pc寄存器值指向函数。上图中的eax = 2,就是在准备参数,为中断服务程序提供参数。

中断与系统调用

为什么缺页中断,除0中断,I/O中断不用传参数,凭什么INT 80就要传参数?为了理解这个问题,我们还需要多一点逼数。

可以理解INT 80,这个中断处理程序和其他中断处理程序有一些不一样。INT 80这个中断处理程序,要比其他中断处理程序要复杂,作为一个转发中心,它需要更多信息来确定它该调用哪一个系统函数。至于问为什么要这样设计?当然是为了节约宝贵的指令位数,同时易于扩展。若每一个系统调用都要求在自己在中断向量表中有一席之地(共有190多个系统调用),试想为了表示这样的数INT x(x > 256),INT这条指令中的立即数位,是不是要增加呢?同时,系统若增加了新的系统调用,比如在linux随后版本系统中新增的epoll这个系统调用,我们只用修改系统调用表,在表中添上epoll这个表项,就可以方便的通过更改参数,来快捷的调用epoll,而不用从指令上做修改。

2.正题

在认真看完了上面的引言之后,虽然有了逼数明白了大概代码架构逻辑,但我们还有落地,我们仍处于空战状态,空对空打嘴炮的状态。所以要来一段源码,验证是否与上面所写框架一致。

linux-5.0.1/arch/x86/entry/syscalls/syscall_32.tbl,以下列出socket相关的系统调用接口,以及对应的系统调用号和内核的socket接口。

 i386    socketcall      sys_socketcall          __ia32_compat_sys_socketcall
i386 socket sys_socket __ia32_sys_socket
i386 socketpair sys_socketpair __ia32_sys_socketpair
i386 bind sys_bind __ia32_sys_bind
//sys_socketcall片段
switch (call) {
case SYS_SOCKET:
err = __sys_socket(a0, a1, a[]);
break;
case SYS_BIND:
err = __sys_bind(a0, (struct sockaddr __user *)a1, a[]);
break;
case SYS_CONNECT:
err = __sys_connect(a0, (struct sockaddr __user *)a1, a[]);
break;
case SYS_LISTEN:
err = __sys_listen(a0, a1);
break;
case SYS_ACCEPT:
err = __sys_accept4(a0, (struct sockaddr __user *)a1,
(int __user *)a[], );
break;
case SYS_GETSOCKNAME:
err =
__sys_getsockname(a0, (struct sockaddr __user *)a1,
(int __user *)a[]);
break;
case SYS_GETPEERNAME:

所以这两段代码在说什么呢。INT 80进入到sys_call这个函数,这个函数实现上是switch,如果在进入sys_call这个函数时,传入102,那么就会跳转到sys_sokcetcall这个函数中去,然后我们在sys_sokcetcall函数中又看到了switch函数。根据你进入到sys_sokcetcall函数所传入的参数,将调用不同的系统函数。
在这里一个有趣的地方是,sys_call函数中,是可以直达sys_bind,sys_socket这类函数的,为什么还要设计一个socketcall函数,来调用?为了让你能够准确理解文字和代码所表述的意思,我又画了张图。

震惊,是谁丧尽天良写出这样的代码架构?居心何在?

图说socket与系统调用代码架构的更多相关文章

  1. 【转】Android bluetooth介绍(二): android blueZ蓝牙代码架构及其uart 到rfcomm流程

    原文网址:http://blog.sina.com.cn/s/blog_602c72c50102uzoj.html 关键词:蓝牙blueZ  UART  HCI_UART H4  HCI  L2CAP ...

  2. socket相关系统调用的调用流程

    最近一直在读内核网络协议栈源码,这里以ipv4/tcp为例对socket相关系统调用的流程做一个简要整理,这些相关系统调用的内部细节虽然各有不同,但其调用流程则基本一致: 调用流程: (1)系统调用 ...

  3. Socket与系统调用深层分析

    实验背景: Socket API编程接口之上可以编写基于不同网络协议的应用程序: Socket接口在用户态通过系统调用机制进入内核: 内核中将系统调用作为一个特殊的中断来处理,以socket相关系统调 ...

  4. 出现socket:(10107)系统调用失败

    在编译vue项目,npm run dev出现 socket:(10107)系统调用失败  解决方案: 以管理员身份打开cmd,使用以下命令:     netsh winsock reset 重启电脑即 ...

  5. Libvirt代码架构

    Libvirt介绍 参考资料 Libvirt学习 通过virsh了解libvirt api的调用方式 通过virHypervisorDriver了解libvirt api的实现 virsh代码阅读 通 ...

  6. Socket与系统调用深度分析

    学习一下对Socket与系统调用的分析分析 一.介绍 我们都知道高级语言的网络编程最终的实现都是调用了系统的Socket API编程接口,在操作系统提供的socket系统接口之上可以建立不同端口之间的 ...

  7. 代码架构.md

    代码架构 待办 昨天待办 decription decription 我的流程逻辑(异常处理方式) 1568097677501.drawio.html 29.94 KB 异常的两种处理方式 异常的两种 ...

  8. 巡风代码架构简介以及Flask的项目文件结构简介

    一.巡风: 巡风是一款什么东西,想必安全同行都不陌生吧.用它作为内网漏洞扫描管理架构是一种很好的选择,扫描快,开源,还可自己编写符合规则的POC直接放入相应目录来扩展.今天下午趁着有点时间捋了一下巡风 ...

  9. linux socket编程系统调用栈

    目录 一.网络协议参考模型简介 二.SOCKET概述 三.SOCKET基本数据结构 1.TCP通信编程 2.服务器端实例代码 3.客户端实例代码 4.头文件socketwrapper.h 5.程序实现 ...

随机推荐

  1. BZOJ4406 WC2016 论战捆竹竿

    Problem BZOJ Solution 显然是一个同余系最短路问题,转移方案就是所有|S|-border的长度,有 \(O(n)\) 种,暴力跑dijkstra的复杂度为 \(O(n^2\log ...

  2. (2)打鸡儿教你Vue.js

    var obj = {} Object.defineProperty(obj, 'msg', { // 设置 obj.msg = "1" 时set方法会被系统调用 参数分别是设置后 ...

  3. 在docker容器中编译hadoop 3.1.0

    在docker容器中编译hadoop 3.1.0 优点:docker安装好之后可以一键部署编译环境,不用担心各种库不兼容等问题,编译失败率低. Hadoop 3.1.0 的源代码目录下有一个 `sta ...

  4. base/7/x86_64/filelists_db FAILED

      解决办法: [root@localhost ~]# cd /var/lib/rpm [root@localhost rpm]# rm -rf __db.* # 清除原 rpmdb 文件 [root ...

  5. 20191214数组之四:数字不相同的完全平方数(关于数位上数字判断与sprintf)

    sprintf用法参见之前的随笔;(以解决):

  6. zabbix(12)使用Grafana

    一.Grafana介绍 Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知.它主要有以下六大特点: 1.展示方式:快速灵活的客户端图表,面板插 ...

  7. “可恶”的mariadb

    这是头一次用mariadb,听说是centos7自带的,本来本地用的好好地,今天想连接一下远程centos7主机上的mariadb,结果各种出错,痛不欲生,最后实在买办法只能卸载装mysql啦.稍微记 ...

  8. Mininet系列实验(三):Mininet命令延伸实验扩展

    1 实验目的 熟悉Mininet自定义拓扑三种实现方式:命令行创建.Python脚本编写.交互式界面创建. 2 实验原理 Mininet 是一个轻量级软件定义网络和测试平台:它采用轻量级的虚拟化技术使 ...

  9. linux下 安装 ImageMagick 及其 php imagick扩展(转)

    linux下 安装 ImageMagick 及其 php imagick扩展 PHP版本7.1.3 : ImageMagick版本 ImageMagick-7.0.8-3: PHP扩展imagick版 ...

  10. oracle中的cursor

    游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来 ...