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

2023-05-16

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


首先我选择的系统调用是122号系统调用——uname

简单的介绍一下uname,它的功能是获取当前内核名称和其他信息。


用法:
#include <sys/utsname.h>


/* Put information about the system in NAME.  */
extern int uname (struct utsname *__name) __THROW;
参数:
__name:指向存放系统信息的缓冲区,原型如下

/* Structure describing the system and machine. */
struct utsname
  {
    /* Name of the implementation of the operating system. */
    char sysname[_UTSNAME_SYSNAME_LENGTH];   //当前操作系统名

    /* Name of this node on the network. */
    char nodename[_UTSNAME_NODENAME_LENGTH]; //网络上的名称

    /* Current release level of this implementation. */
    char release[_UTSNAME_RELEASE_LENGTH];   //当前发布级别


    /* Current version level of this release. */
    char version[_UTSNAME_VERSION_LENGTH];   //当前发布版本

    /* Name of the hardware type the system is running on. */
    char machine[_UTSNAME_MACHINE_LENGTH];   //当前硬件体系类型

#if _UTSNAME_DOMAIN_LENGTH- 0
    /* Name of the domain of this node on the network. */
# ifdef __USE_GNU
    char domainname[_UTSNAME_DOMAIN_LENGTH];  //当前域名
# else
    char __domainname[_UTSNAME_DOMAIN_LENGTH];
# endif
#endif
  };

返回说明:
成功执行时,返回0。失败返回-1,errno被设为EFAULT,表示buf无效。

根据相关例程很容易的就写出了一个c语言的应用。


编译运行。


正确的显示了系统的信息。


但是当我使用汇编编写时,一开始也是参照老师的方法去写,也就是定义一个指向struct utsname的指针,并作为汇编中系统调用的返回值,结果什么也没显示出来。

后来我发现了问题所在,关注一下uname的api函数的原型 extern int uname (struct utsname *__name) __THROW;

很明显他的返回值并不是系统讯息的内容,而是成功执行时,返回0。失败返回-1,errno被设为EFAULT,表示buf无效。系统信息的指针是作为函数的输入参数。豁然开朗

既然eax存的是系统调用编号,ebx是第一个输入参数,那么我将指针存进ebx不就ok了?同时为了验证eax内是返回值的猜想,我定义了一个int变量k,并且将其赋值为-1,,通过if判断如果在系统调用后uname不返回0,就无法打印出内容。

可以看到在嵌入式汇编语句中不单单有输出参量,还有了输入参量 u,后面的(b)就是存入ebx的意思了。

编译执行

结果是确实有显示了,但是那个段错误是什么鬼?代码泄漏? 这里我真的没太明白了,希望大家能够帮我指出问题所在。

但另一方面能能打印出东西说明k值改变了,后来我打印了k,确实k值为0。

这说明在int 0x80时此时输入的参量将在ebx中(我觉得其实调用号也可以理解成一种输入参量吧,它存在eax中),在int后,返回值就存在eax中。


经高人指点我发现了问题所在

对指针的理解还是太年轻,我光定义指针 但实际上根本没有开辟空间存uname的东西,指针是野指针能不出问题吗!

改为这样就ok了,定义结构体变量,将结构体的地址作为参数传进去就好了。



改为这样就ok了(可看到sysnamne左边的那个就是k,确实返回了0)




具体的调用过程这里借用课件中的一张图


显然在调用之前,先保存了现场(SAVE_ALL具体内容课上已讲),再根据eax中的调用号和调用表(sys_call_table)进行调用,然后将返回值保存在eax中。最终离开系统调用并恢复现场,同时根据任务是否满足运行条件来调度任务(call schedule)。

总结一下,其实这种软中断非常像单片机中各种”软中断“,而系统调用的整个过程就是一种”中断响应“只不过,中断源并不是外部设备的信号或是定时器/计数器产生的信号而是由软件代码产生的中断信号,而系统调用号就是一种中断向量,它指向了该系统调用服务程序的入口。

也就是第一层皮:程序的入口API。

第二层:系统调用的handle。

第三层:系统调用的服务程序。




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 平衡小车卡尔曼滤波算法

    最近研究STM32的自平衡小车 xff0c 发现有两座必过的大山 xff0c 一为卡尔曼滤波 xff0c 二为PID算法 网上看了很多关于卡尔曼滤波的代码 xff0c 感觉写得真不咋地 一怒之下 xff0c 自己重写 xff0c 不废话 x
  • FreeRTOS学习-前言与FreeRTOS发行版

    1 前言 因为工作的需要 xff0c 学习FreeRTOS已经有一段时间了 接下来一段时间会定期更新本人学习FreeRTOS的系列笔记 系列笔记主要参考了官方的说明手册和FreeRTOS的源代码 其主要思想是先了解FreeRTOS的对外接口
  • FreeRTOS学习-内存管理

    1 动态内存分配与FreeRTOS 从v9 0 0后 xff0c FreeRTOS开始支持内核对象的静态分配方式 xff0c 因此 xff0c 内存管理库可以被裁剪 但在大多数嵌入式应用中 xff0c 堆的使用还是非常常见的 因此 xff0
  • FreeRTOS学习-任务管理(Task管理)(1)

    1 简介 任务管理 xff08 或称进程管理 xff09 是所有操作系统内核的最基本组成模块之一 xff0c FreeRTOS也不例外 想要了解一个操作系统 xff0c 不得不理解其任务管理的设计和实现 任务管理的介绍由两篇文章组成 xff
  • Java基础之Java枚举

    絮叨 昨天刚好有遇到一个枚举的小问题 xff0c 然后发现自己并不是那么熟悉它 xff0c 然后在开发中 xff0c 枚举用的特别多 xff0c 所以有了今天的文章 什么是枚举 Java中的枚举是一种类型 xff0c 顾名思义 xff1a
  • C++ STL 移动一个vector的元素到另一个vector

    1 背景 有的时候 xff0c 我们需要提取某个现有的vector中的元素到另一个vector中 xff0c 或者对多维的vector进行纬度的转换 在这种场景下 xff0c 往往原始的vector中的数据可能并不需要了 xff0c 为了节
  • Qt/C++ 临时屏蔽控件信号(signal)的实用方法

    1 背景 在使用Qt的控件时 xff0c 我们大概率会使用Qt的信号与槽 xff08 signal slot xff09 的机制来实现自己的UI交互逻辑 由于Qt内置控件的信号种类是有限的 xff0c 我们常常会遇到如下窘境 xff1a 以
  • FreeRTOS学习-队列管理

    1 简介 在FreeRTOS中 xff0c 提供了多种任务间通讯的机制 xff0c 包括消息队列 信号量和互斥锁 事件组 任务通知 xff0c 他们的总体特征如下图所示 xff1a 从图中可以看出 xff0c 消息队列 信号量和互斥锁 事件
  • Qt/C++ 如何删除QListWidget的指定项

    1 简介 QListWidget是Qt中 xff0c 用于展示列表类型数据的常用控件 它提供了一个类似于QListView的列表视图 xff0c 但是具有用于添加和删除项的接口 QListWidget使用一个内部模型来管理列表中的每个QLi
  • C++ std::result_of/std::invoke_result的简明指南

    1 简介 在C 43 43 中 xff0c 有时我们需要获取函数或可调用对象的返回值类型 xff0c 以便进行后续的操作 xff0c 在泛型编程中很常用 xff0c 特别是当不同的参数集的结果类型不同时 在早期的C 43 43 版本中 xf
  • FreeRTOS学习-任务通知(Task Notification)

    1 简介 任务通知本质上就是一种进程间通信机制 之前的文章介绍的消息队列 事件组 信号量等都是一种间接的通信方式 xff0c 而任务通知则是更加直接的方式 xff0c 允许两个任务 xff08 或中断和任务 xff09 之间直接通信 2 任
  • 异常行为分析模型设计

    本文针对异常访问现状及问题进行简要描述 xff0c 在此基础上提出基于一元线性回归的最小二乘法异常访问分析模型 xff0c 通过该模型解决了异常访问中时间与访问间相关性问题 异常访问是指网络行为偏离正常范围的访问情况 异常访问包含多种场景
  • 无人机PX4学习(1)

    内容源自 xff1a PX4飞控用户手册 链接 xff1a https docs px4 io master en Basic concepts Drone an unmanned 34 robotic 34 vehicle that ca
  • 无人机PX4学习(2)

    内容源自 xff1a PX4飞控用户手册 链接 xff1a https docs px4 io master en getting started flight controller selection html Flight Contro
  • 无人机PX4学习(3)

    内容源自 xff1a PX4飞控用户手册 链接 xff1a PX4 Flight Modes Overview PX4 User Guide Flight Mode Section RC或GCS上可以切换飞行模式 xff0c 但有些模式有限
  • 两篇论文入坑AIOps异常检测

    AIOps简介 以下部分内容来源于清华大学裴丹教授发表在 中国计算机学会通讯 第13卷第12期的专栏 基于机器学习的智能运维 我们都知道 xff0c 当代社会生活中的大型软硬件系统为了确保能够安全 可靠地运行 xff0c 需要有专业的运维人
  • python代码,两个4*4旋转矩阵之间的位姿变化,相对旋转矩阵

    python代码 xff0c 两个4 4旋转矩阵之间的位姿变化 xff0c 也就是求两个旋转矩阵之间的相对旋转矩阵 import numpy as np def get transform matrix rot mat1 rot mat2
  • crazyS中给firefly飞机添加两个相机

    firefly飞机中原本只有一个相机 xff0c 由于项目需要一个飞机去识别前方两架飞机 xff0c 因此需要增加一个相机 在rotors descriptioin gt urdf gt mav with vi sensor中可以看到此处
  • gitee(码云)和gitHub的区别

    1 gitee与gitHub概念 xff1f Gitee xff08 码云 xff09 是开源中国社区推出的代码托管协作开发平台 xff0c 支持Git和SVN xff0c 提供免费的私有仓库托管 Gitee专为开发者提供稳定 高效 安全的
  • 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    郭孟琦 43 原创作品转载请注明出处 43 Linux内核分析 MOOC课程http mooc study 163 com course USTC 1000029000 首先我选择的系统调用是122号系统调用 uname 简单的介绍一下un