IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 系统调用:用户级函数如何通过INT 80中断进入操作系统内核 -> 正文阅读

[C++知识库]系统调用:用户级函数如何通过INT 80中断进入操作系统内核

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才是真正的处理函数,可以对内核中的数据进行读取,也就是所谓的系统调用

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 21:57:07  更:2022-03-11 21:59:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:19:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码