系统调用:用户级函数如何通过INT 80中断进入操作系统内核

2023-11-20

printf()打印内核中的一段字符串为例

  1. printf()是用户函数无法进入内核,因此需要进行系统调用,进入内核的方式是使用int 0x80中断

  2. printf()函数想要进入系统内核是通过系统调用write()实现

    /*
     * 位置:linux/lib/write.c
     */
    #define __LIBRARY__
    #include <unistd.h>
    _syscall3(int,write,int,fd,const char *,buf,off_t,count)
    
  3. _syscall3被展开成一段包含int 0x80中断汇编代码的C代码,见下文代码

    /*
     * 位置:include/unistd.h
     */
    ...
    #define __NR_write	4
    ...
    /*
     * 定义了一个返回值 long型变量:__res
     * __asm__ 表示准备内嵌汇编代码 volatile表示编译器不对代码进行优化
     * "int $0x80" 表示调用int 0x80中断
     */
    #define _syscall3(type,name,atype,a,btype,b,ctype,c) \
    type name(atype a,btype b,ctype c) \
    { \
    long __res; \  					
    __asm__ volatile ("int $0x80" \	
    	: "=a" (__res) \					
    	: "0" (__NR_##name),"b" ((long)(a)),"c" ((long)(b)),"d" ((long)(c))); \
    if (__res>=0) \
    	return (type) __res; \
    errno=-__res; \
    return -1; \
    }
    /*
    // 指明%ebx中存放了输入参数a,也即实际的操作为:将参数a赋值给%ebx中
    // 指明%ecx中存放了输入参数b,也即实际的操作为:将参数b赋值给%ecx中
     * 注意:AT&T语法中
     * $表示立即数  %表明这是一个寄存器
     * 17行:"=a" 指定输出操作数的典型规则,'=' 是输出操作数的特有字段,表明只写;
     * 17行:'a'表明先将结果输出到%eax中,然后再由%eax输出到__res中
     * 18行:输入参数的规则
     * 18行:"0"表明和输出寄存器是同一个寄存器,也即%eax,意思是输入参数__NR_##name会存放在%eax中
     * 18行:"b"((long)(a))表明输入参数a会放在寄存器%ebx中,也即会将参数a先存储到%ebx中
     * 
     * 综上:该内嵌代码的意思是:
     * 调用int 0x80中断
     * 输入参数是__NR_##name、a、b、c
     * 返回值先存放在%eax中,然后再赋值到__res中
     */
    

    因此_syscall3(int,write,int,fd,const char *,buf,off_t,count)其展开后结果如下所示:

    请添加图片描述

  4. 通过int 0x80中断,代码将进入系统内核

    操作系统的已经做好准备工作如下示:

    main.c中初始化

    请添加图片描述

    ②在函数sched_init()中设置系统调用中断门,引导int 0x80中断,可以看到该中断需要靠system_call函数处理

    请添加图片描述

    int 0x80中断的处理,set_system_gate()其实就是宏_set_gate()

    请添加图片描述
    请添加图片描述

    ④宏_set_gate()也是嵌入汇编指令,其中的addr&system_call,是个地址;该宏主要就是初始化好了IDT表int 0x80对应的表项

    • 上述的&idt即为IDT表的起始位置,所以&idt[n](这里n=0x80)就表示中断0x80对应的表项在IDT表中位置
    • 设置好CS=8,其中CPL=0
    • 设置好IP=addr

    ⑤如此一来,当int 0x80中断来的时候,根据CS = 8 也即段选择子为8,就可以去GDT表中找到真正要执行的代码的段基地址,然后结合IP的偏移,找到INT 0x80的实际处理函数system_call

  5. 下面我们进入system_call代码,也即真正的中断处理程序linux/kernel/system_call.s在程序中,跳到一个表里面的一个函数地址

    请添加图片描述

    _sys_call_table是一个函数地址表,其中write对应的处理函数的地址就放在表的%eax索引处

    请添加图片描述

  6. 然而sys_write才是真正的处理函数,可以对内核中的数据进行读取,也就是所谓的系统调用

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

系统调用:用户级函数如何通过INT 80中断进入操作系统内核 的相关文章

  • 如何调试参数化 SQL 查询

    我使用 C 连接到数据库 然后使用 Ad hoc SQL 来获取数据 这个简单的 SQL 查询非常方便调试 因为我可以记录 SQL 查询字符串 如果我使用参数化 SQL 查询命令 有没有办法记录 sql 查询字符串以进行调试 我想就是这样的
  • 处理 LINQ sum 表达式中的 null

    我正在使用 LINQ 查询来查找列的总和 并且在少数情况下该值有可能为空 我现在使用的查询是 int score dbContext domainmaps Where p gt p SchoolId schoolid Sum v gt v
  • 实体框架代码优先 - 在另一个文件中配置

    使用 Fluent API 将表到实体的映射分开的最佳方法是什么 以便它全部位于单独的类中 而不是内联在 OnModelCreating 方法中 我目前在做什么 public class FooContext DbContext prote
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • Capistrano 3 部署无法连接到 GitHub - 权限被拒绝(公钥)

    我使用 Capistrano v3 和 capistrano symfony gem 设置了以下部署脚本 我正在使用 Ubuntu 14 4 部署到 AWS EC2 实例 我正在连接从 AWS 下载的 pem 文件 我的deploy rb中
  • 我应该在单元测试中使用 AutoMapper 吗?

    我正在为 ASP NET MVC 控制器方法编写单元测试 这些控制器依赖于IMapper 我创建的用于抽象 AutoMapper 的接口 使用 Castle Windsor 通过构造函数注入传入 动作方法使用IMapper从领域对象映射到
  • 阅读 Stack Overflow RSS 源

    我正在尝试获取未回答问题的列表the feed https stackoverflow com feeds 但我在阅读时遇到困难 const string RECENT QUESTIONS https stackoverflow com f
  • Qt中正确的线程方式

    我的图像加载非常耗时 图像很大 并且在加载时也完成了一些操作 我不想阻止应用程序 GUI 我的想法是在另一个线程中加载图像 发出图像已加载的信号 然后用该图像重绘视图 我的做法 void Window loadImage ImageLoad
  • git 错误:无法处理 https

    当我尝试使用 git clone 时https xxx https xxx我收到以下错误我不处理协议 https 有人可以帮我吗 完整消息 dementrock dementrock A8Se git 克隆https git innosta
  • 如何检测斑点并将其裁剪成 png 文件?

    我一直在开发一个网络应用程序 我陷入了一个有问题的问题 我会尝试解释我想要做什么 在这里您看到第一个大图像 其中有绿色形状 我想要做的是将这些形状裁剪成不同的 png 文件 并使它们的背景透明 就像大图像下面的示例裁剪图像一样 第一张图像将
  • C#:使用 System.Text 和 System.Text.RegularExpressions 之间的区别

    在 ASP NET C 应用程序中 我注意到为了使用 Regex 和 StringBuilder 我必须将两者都放在 using System Text using System Text RegularExpressions 从简单的角度
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 为什么以下代码不允许我使用 fgets 获取用户输入但可以使用 scanf?

    这是一个更大程序的简短摘录 但该程序的其余部分无关紧要 因为我认为我能够隔离该问题 我怀疑这与我使用 fgets 的方式有关 我读过 最好使用 fgets 而不是 scanf 但我似乎无法让它在这里正常工作 当我使用以下代码时 程序不会给我
  • 使用 Linq 进行异步Where过滤

    我有一个List通过填充的元素async调用 WebService 没问题 我需要过滤该列表以便在应用程序视图上显示某些内容 我试过这个 List
  • 标准 C 中的 sizeof 与 sizeof()? [复制]

    这个问题在这里已经有答案了 我看到一些直接使用 sizeof 的代码 想知道它是否是标准 C 令我惊讶的是 它运行得很好 这是一个例子 include
  • 便携式终端

    有没有办法根据所使用的操作系统自动使用正确的 EOL 字符 我在想类似的事情std eol 我知道使用预处理器指令非常容易 但很好奇它是否已经可用 我感兴趣的是 我的应用程序中通常有一些消息 稍后我会将这些消息组合成一个字符串 并且我希望将
  • 多个同名内存数据库

    关系到这个答案 https stackoverflow com a 48446491 596758 我试图通过设置让多个上下文工作UseInMemoryDatabase以同名 下面的测试失败 第二个上下文为空 我还需要做什么才能在内存数据库
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么
  • ASP.NET Core:会话 ID 始终变化

    今天启动了一个全新的 ASP NET Core 网站 按照说明添加会话 我们在索引页上打印出会话 ID 它始终是唯一的 我认为这可能是 cookie 合规性 所以我在 Chrome 的高级设置和调试器中删除了所有 cookie 但横幅不会再
  • 在 C# 中读取/写入命令行程序

    我正在尝试与 C 的命令行程序进行对话 它是一个情绪分析器 它的工作原理如下 CMD gt java jar analyser jar gt Starting analyser 这是我想从我的 C 程序插入内容的地方 例如 I love y

随机推荐

  • 阿兰·麦席森·图灵 介绍

    Alan MAthison Turing 英国数学家 逻辑学家 被称为 计算机科学之父 人工智能之父 她曾协助盟军破解德国的著名密码系统Enigma 帮助盟军取得了第二次世界大战的胜利 他对计算机的贡献在于他提出的有限状态自动机也就是图灵机
  • 微信支付商家转账到零钱功能使用教程

    之前的 企业付款到零钱 功能 微信支付已下架 以后用 商家转账到零钱 功能取代 下面介绍如何开通并使用该功能 从运营账户支出 首先需要先去了解一下微信支付的这3个账户的关系 商家转账到零钱 功能 是从运营账户转账给用户的 开通 商家转账到零
  • ATL字符串转换宏

    有比MultiByteToWideChar和WideCharToMultiByte更简单的字符串转换宏 你相信吗 头文件 d program files microsoft visual studio 8 vc atlmfc include
  • Flutter 碰到的各种坑 持续更新

    Android转flutter 也有1年多了 在新公司将一个产品用flutter从零开始开发 感觉flutter 还是不太稳定 各种问题还是比较多 总之这次体验还是比较差 Error on line 21 column 5 of pubsp
  • Kafka——Mac搭建kafka环境

    1 下载Kafka安装包 下载地址 将压缩包移动到 usr local mv kafka 2 12 3 1 0 tgz usr local 解压 tar zxvf kafka 2 12 3 1 0 tgz 2 启动 启动zookeeper
  • WEB安全测试手册

    概述 目的 适用读者 适用范围 注意事项 测试级别说明 测试过程示意图 1 服务器信息收集 1 1 运行帐号权限测试 1 2 Web服务器端口扫描 1 3 HTTP方法测试 1 4 HTTP PUT方法测试 1 5 HTTP DELETE方
  • 前端例程20211213:网页去色(以灰度形式显示)

    文章目录 前言 实现与演示 前言 在每年的一些特殊的日子 比如公祭日等 很多网站会将页面整体去色以灰度形式显示 以示哀悼 这里将对网页中实现该功能进行简单说明 实现与演示 使用CSS的 filter grayscale 属性可以给元素添加灰
  • 主进程退出后子进程还会存在吗?_深度好文

    干了这碗鸡汤 我急切地盼望着可以经历一场放纵的快乐 纵使巨大的悲哀将接踵而至 我也在所不惜 太宰治 人间失格 大家好 这里是周日凌晨4点 仍在笔耕不辍的程序喵大人 下面隆重推出我呕心沥血 耗时半个月完成的精心力作 01 什么是进程 标准定义
  • Element Plus 配置自动按需引入后,手动引入组件,组件样式丢失

    起因 最近在尝试使用 Element Plus 写一些简单的页面 跟着官方文档走配置了自动按需引入 npm install D unplugin vue components unplugin auto import vite config
  • IDEA全局搜索框打不开,全局搜索不全,全局搜索不到解决办法

    IDEA默认全局搜索快捷键是Ctrl Shift F 当我在使用IDEA的全局搜索时 发现IDEA的全局搜索快捷键不起作用 无法弹出全局搜索框 此时想到了应该是快捷键被占用了 首先想到的就是搜狗输入法 打开搜狗输入法设置 高级 把这个简繁切
  • Python 基于BP神经网络的鸢尾花分类

    本文用Python实现了BP神经网络分类算法 根据鸢尾花的4个特征 实现3种鸢尾花的分类 算法参考文章 纯Python实现鸢尾属植物数据集神经网络模型 2020 07 21更新 增加了分类结果可视化result visualization
  • Elasticsearch 索引模板:优化大数据搜索与分析

    Elasticsearch 是一个强大的分布式搜索和分析引擎 广泛应用于处理大数据量的搜索和分析任务 为了提高搜索效率和数据组织结构的一致性 Elasticsearch 提供了索引模板 template 的功能 索引模板允许我们在创建索引时
  • 《python语言程序设计》第5章 第23题 贷款计算

    LOAN AMOUNT 10000 number years 5 NUMBER OF YEAR number years 12 interest rate 5 month rate interest rate 1200 print f Lo
  • springboot跳转页面

    SpringBoot里面只有src目录 在src main resources下面有两个文件夹 static 和 templates springboot默认static中放静态页面 而templates中放动态页面 themleaf和fr
  • Egret游戏通用开发框架

    地址 https github com yicaoyimuys EgretGameEngine 简介 现在这套代码已经有几个项目都在使用了 主要用于各项目组间统一开发规范 便于开发人员调整 以及新手快速熟悉项目 支持Egret2 0 x和2
  • C#写的34401A串口232数据读取程序

    首先呢 请先设置惠普表为Talk only模式 也就是31 还不明白的自己查手册去 另外 各个表设置不一样 比如我这里2块表就不一样 一块是7位数据位 even校验 另一块是8位数据位 none校验 具体的可以看看表里的i o那里的设置 数
  • GPIO的两种引脚规则:BCM与BOARD

    树莓派 raspberry 针脚在python中BCM与BOARD模式的区别 在python程序中定义的GPI针脚有两种模式 BCM模式 BOARD模式 BCM模式 例如 GPIO setmode GPIO BCM 测试结果如下 物理针脚1
  • pycharm注释快捷键Ctrl+/

    行注释 取消行注释 Ctrl 块注释 Ctrl Shift
  • ArcGIS部分问题解决办法

    ArcGIS部分常见问题解决办法 最近在学习ArcGIS过程中 进行某些操作选项总是会会发生错误 不仅仅我自己一个人是这样 周围好多同学也是经常在操作的过程中报错 所以就很突发奇想把这段时间遇到的问题统一写下来 也是为了自己以后忘掉可以直接
  • 系统调用:用户级函数如何通过INT 80中断进入操作系统内核

    以printf 打印内核中的一段字符串为例 printf 是用户函数无法进入内核 因此需要进行系统调用 进入内核的方式是使用int 0x80中断 printf 函数想要进入系统内核是通过系统调用write 实现 位置 linux lib w