博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Linux内核原理与分析》第五周作业
阅读量:6528 次
发布时间:2019-06-24

本文共 2025 字,大约阅读时间需要 6 分钟。

课本:第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语言代码如下:

1508801-20181111161306882-216384950.png
在Code文件夹中,我已经建立好一个名为“gzc.c”的文件,如图所示:
1508801-20181111161442451-1929006985.png
gcc执行上述C语言代码,成功改名,如图所示:
1508801-20181111161610276-1702307499.png
经查询,rename()的系统调用号为38:
1508801-20181111161744389-435026603.png
38的16进制数为0x26。所以,编写汇编代码将其嵌入C语言代码,代码如下:
1508801-20181111163922085-769634657.png

#include
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”,程序同样成功执行:

1508801-20181111164417497-48295957.png
下面对嵌入的汇编代码进行分析:

"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,程序正常运行,如下所示:

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

转载于:https://www.cnblogs.com/intoxication/p/9942595.html

你可能感兴趣的文章
三端稳压器各个参数解释
查看>>
算法(Algorithms)第4版 练习 1.3.14
查看>>
mysql 自动化脚本备份
查看>>
virtual PC 打造IE6、IE7、IE8、IE9等多版本共存原版测试环境
查看>>
js面向对象1
查看>>
内部类
查看>>
高速数论变换(NTT)
查看>>
Springmvc的跳转方式
查看>>
加密原理介绍,代码实现DES、AES、RSA、Base64、MD5
查看>>
LINUX中常用操作命令
查看>>
python 获取进程pid号
查看>>
链表中插入一个节点的三种情况
查看>>
洛谷.4180.[模板]次小生成树Tree(Kruskal LCA 倍增)
查看>>
TCL函数“参数自动补全” 与 “help 信息显示”
查看>>
POJ1050To the Max
查看>>
汇编基础--标识符、标号、伪指令和指令
查看>>
将公用文件夹从Exchange2010迁移到 Exchange 2013
查看>>
动态规划算法
查看>>
WebService学习总结(二)——WebService相关概念介绍
查看>>
泥鳅般的const(一个小Demo彻底搞清楚)
查看>>