课本:第4章 系统调用的三层机制(上)

-用户态、内核态和中断

-用户态:在低的执行级别下,代码能够掌控的范围有所限制,只能访问部分内存。

-内核态:在高的执行级别下,代码可以执行特权指令,访问任意的物理内存。

-中断:从用户态进入内核态的主要方式。

-中断类别

- 硬件中断:在用户态进程执行时,硬件中断信号到来,进入内核态,就会执行这个中断对应的中断服务例程。

- 软中断:在用户态进程执行过程中,调用了一个系统调用(一种特殊中断),进入内核态。

  • 寄存器上下文切换

    当用户态切换到内核态时,就要把用户态寄存器上下文保存起来,同时把内核态的寄存器的值放到当前CPU中。int指令触发中断机制会在堆栈上保存一些寄存器的值,会保存用户态栈顶地址、当时的状态字、当时的CS:EIP的值。同时会将内核态的栈顶地址、内核态的状态字放入CPU对应的寄存器,并且CS:EIP寄存器的值会指向中断处理程序的入口,对于系统调用来说是指向system_call。int指令或中断信号发生之后,第一件事就是保存现场,进入中断处理程序,执行SAVE_ALL。中断处理程序结束后,中断处理结束前的最后一件事是恢复现场,执行RESTORE_ALL。
  • API和系统调用关系
    • API:应用程序编程接口,只是函数定义。
    • 系统调用:是通过软中断向内核发出了中断请求,int指令的执行就会触发一个中断请求。

      libc函数库定义的一些API内部使用了系统调用的封装例程,其主要目的是发布系统调用,使程序员在写代码时不需要用汇编指令和寄存器传递参数来触发系统调用。一个API可能只对应一个系统调用,亦可能内部由多个系统调用实现,一个系统调用也可能被多个API调用。
  • Intel x86 CPU定义了4种不同的执行级别0、1、2、3,数字越小特权越高。Linux系统采用了其中的0、3两个特权级别。

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

在实验楼环境中,我使用rename()系统调用来实现了将同目录下的文件更改文件名,C语言代码如下:



在Code文件夹中,我已经建立好一个名为“gzc.c”的文件,如图所示:



gcc执行上述C语言代码,成功改名,如图所示:



经查询,rename()的系统调用号为38:



38的16进制数为0x26。所以,编写汇编代码将其嵌入C语言代码,代码如下:

#include<stdio.h>

int main()
{
char *old_name = "gzc123.c";
char *new_name = "gzc.c";
int ret;
asm volatile(
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl $0x26,%%eax\n\t" //syscall num of rename in HEX is 0x26
"int $0x80\n\t"
:"=a"(ret)
:"b"(old_name),"c"(new_name)
);
if(ret<0)
printf("error!\n");
else
printf("successful!\n");
return 0;
}

因为刚才在执行纯C语言程序时已经将文件名改为"gzc123.c",这里的汇编代码嵌入C代码是将“gzc123.c”改为“gzc.c”,程序同样成功执行:



下面对嵌入的汇编代码进行分析:

"movl %1,%%ebx\n\t" //将old_name的值放入ebx
"movl %2,%%ecx\n\t" //将new_name的值放入ecx
"movl $0x26,%%eax\n\t" //syscall num of rename in HEX is 0x26
"int $0x80\n\t" //触发系统调用
:"=a"(ret) //将eax的值写入ret
:"b"(old_name),"c"(new_name) //分别代表上面的%1,%2

总结

本次实验总体来说没有遇到什么编码理解上的问题,仅仅遇到了一个小问题,就是在实验楼环境执行代码编译完成后的可执行程序时提示“权限不足”,解决方法为在执行程序时在前面加上sudo,程序正常运行,如下所示:



本次实验仅使用汇编代码实现了简单的系统调用功能,实验比较容易,但使我对于汇编代码的编写和其执行过程更加熟悉和了解。希望在后面的实验中,理解和编写汇编代码、理解linux内核系统的运行会更加得心应手。

《Linux内核原理与分析》第五周作业的更多相关文章

  1. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  2. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  3. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  4. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  5. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  6. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

随机推荐

  1. win7下Oracle库impdp导入dmp

    第一步:创建备份文件存储目录 create or replace directory back_file as 'D:\app\yangxf\back_or_memery_file'; create ...

  2. 【java】J2EE、J2SE和J2ME的区别

    本文向大家简单介绍一下J2EE.J2SE.J2ME概念及区别,J2EE,J2SE,J2ME是java针对不同的的使用来提供不同的服务,也就是提供不同类型的类库. Java2平台包括:标准版(J2SE) ...

  3. 编码原则 之 Persistence Ignorance

    原文 The principle of Persistence Ignorance (PI) holds that classes modeling the business domain in a ...

  4. sony Z5P 刷rec、root的方法

    想root需要刷第三方recovery,刷recovery需要先解锁.但如果直接解锁,会丧失相机算法.屏幕超逼真模式,所以不能直接来. 大体步骤就是解完锁后自己做个内核刷进去,欺骗系统让他觉得没解锁. ...

  5. Linux下的串口调试工具——Xgcom

    Linux下的串口调试工具——Xgcom xgcom的下载网址:https://code.google.com/archive/p/xgcom/downloads (1)安装必须的库 apt-get ...

  6. OpenStack笔记

    *********virsh xml文件解读****************************** https://libvirt.org/format.html https://libvirt ...

  7. 『Argparse』命令行解析

    一.基本用法 Python标准库推荐使用的命令行解析模块argparse 还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的optparse.因为argparse是 ...

  8. React文档(十七)非受控组件

    大多数情况下,我们建议使用受控组件(也就是用React的state来控制表单元素的value值)来实现表单.在一个受控组件里,表单数据被React组件处理.另一种方案就是非控制组件,这样的话表单数据就 ...

  9. ThinkPHP5.0源码学习之执行应用

    一.应用启动 在/thinkphp/start.php文件中,用一句代码App::run()->send();实现应用的启动. // 执行应用 App::run()->send();   ...

  10. 最近使用Navicat for MySQl访问远程mysql数据库,出现报错,显示“2003- Can't connect MySQL Server on 'localhost'(10038)“。

    优先考虑mysql数据库是否开启 1.先看报错窗口.   通过百度,最终找到的原因是:远程3306端口未对外开放. 于是下面进行远程3306端口开放操作.   首先远程连接服务器,点击“开始”-“管理 ...