20135302魏静静Linux内核分析第二周学习总结
操作系统是如何工作的
1. 小结:计算机是怎样工作的
三个法宝
存储程序计算机、函数调用堆栈、中断机制
两把宝剑
中断上下文、进程上下文的切换
2. 堆栈
- 堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间。
- 函数条用框架
- 传递参数
- 保存返回地址
- 提供局部变量空间...
堆栈相关寄存器:
esp:堆栈指针——指向系统栈最上面一个栈帧的栈顶
ebp: 基址指针——指向系统栈最上面一个栈帧的底部
cs:eip:指令寄存器——指向下一条等待执行的指令地址- 堆栈相关操作:
- push :栈顶地址减少4个字节
- pop: 栈顶地址增加4个字节
- call:将当前cs:eip值压栈,cs:eip指向被调函数入口地址。
- ret:从栈顶弹出原来保存在此的cs:eip值,放入cs:eip中。
leave:当调用函数调用时,一般都有这两条指令
pushl %ebp和movl %esp,%ebp,leave是这两条指令的反操作。
3. 函数调用约定
| 函数调用约定 | 参数传递顺序 | 负责清理参数占用的堆栈 |
|---|---|---|
| __pascal | 从左到右 | 调用者 |
| __stdcall | 从右到左 | 被调函数 |
| __cdecl | 从右到左 | 调用者 |
调用函数的代码和被调函数必须采用相同的函数的调用约定,程序才能正常运行。
Windows中C/C++程序的缺省函数调用约定是__cdecl
linux中gcc默认用的规则是__stdcall
4、C代码中嵌入汇编代码的写法
__asm__(汇编语句模板: 输出部分: 输入部分: 破坏描述部分)
汇编语句模板
汇编语句模板由汇编语句序列组成,语句之间使用“;”、“\n”或“\n\t”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1,…,%9。
输出部分
输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C语言变量组成。
输入部分
输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符由限定字符串和C语言表达式或者C语言变量组成。
破坏描述部分
破坏描述符用于通知编译器我们使用了哪些寄存器或内存,由逗号格开的字符串组成,每个字符串描述一种情况,一般是寄存器名;除寄存器外还有“memory”。
限制字符
限制字符有很多种,有些是与特定体系结构相关,它们的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系。
| 常用限制字符 | ||
|---|---|---|
| 分类 | 限定符 | 描述 |
| 通用寄存器 | “a” | 将输入变量放入eax |
| “b” | 将输入变量放入ebx | |
| “c” | 将输入变量放入ecx | |
| “d” | 将输入变量放入edx | |
| “s” | 将输入变量放入esi | |
| “d” | 将输入变量放入edi | |
| “q” | 将输入变量放入eax,ebx,ecx,edx中的一个 | |
| “r” | 将输入变量放入通用寄存器,也就是eax,ebx,ecx,edx,esi,edi中的一个 | |
| “A” | 把eax和edx合成一个64 位的寄存器(use long longs) | |
| 内存 | “m” | 内存变量 |
| “o” | 操作数为内存变量,但是其寻址方式是偏移量类型,也即是基址寻址,或者是基址加变址寻址 | |
| “V” | 操作数为内存变量,但寻址方式不是偏移量类型 | |
| “ ” | 操作数为内存变量,但寻址方式为自动增量 | |
| “p” | 操作数是一个合法的内存地址(指针) | |
| 寄存器或内存 | “g” | 将输入变量放入eax,ebx,ecx,edx中的一个或者作为内存变量 |
| “X” | 操作数可以是任何类型 | |
| 立即数 | “I” | 0-31之间的立即数(用于32位移位指令) |
| “J” | 0-63之间的立即数(用于64位移位指令) | |
| “N” | 0-255之间的立即数(用于out指令) | |
| “n” | 立即数 | |
| “p” | 立即数,有些系统不支持除字以外的立即数,这些系统应该使用“n”而不是“i” | |
| 匹配 | & | 该输出操作数不能使用过和输入操作数相同的寄存器 |
| 操作数类型 | “=” | 操作数在指令中是只写的(输出操作数) |
| “+” | 操作数在指令中是读写类型的(输入输出操作数) | |
| 浮点数 | “f” | 浮点寄存器 |
| “t” | 第一个浮点寄存器 | |
| “u” | 第二个浮点寄存器 | |
| “G” | 标准的80387浮点常数 | |
| 其它 | % | 该操作数可以和下一个操作数交换位置 |
| # | 部分注释,从该字符到其后的逗号之间所有字母被忽略 | |
| * | 表示如果选用寄存器,则其后的字母被忽略 | |
5.mykernel实验
cd LinuxKernel/linux-3.9.4
qemu -kernel arch/x86/boot/bzImage
然后cd mykernel 可以看到qemu窗口输出的内容的代码mymain.c和myinterrupt.c
进程的启动
/*mymain.c*/
/* start process 0 by task[0] */
pid = 0;
my_current_task = &task[pid];
asm volatile(
"movl %1,%%esp\n\t" /* 将进程的sp赋给esp寄存器 */
"pushl %1\n\t" /* ebp入栈:因为在这里栈为空,esp=ebp,所以push的%1就是esp就是ebp。*/
"pushl %0\n\t" /* 进程入口ip入栈 */
"ret\n\t" /* 把进程入口ip赋给eip,即从这之后0号进程启动。*/
"popl %%ebp\n\t"
:
: "c" (task[pid].thread.ip),"d" (task[pid].thread.sp) /* input c or d mean %ecx/%edx*/
);
进程的切换:
(1).下一个进程next->state == 0 即正在执行时
/*myinterrupt.c*/
//两个正在运行的进程之间做进程上下文切换
if(next->state == 0)
/* state值的含义:-1表示没有执行,0表示正在执行,>0表示停止,这里为0,即进程正在执行 */
{
/* 以下是进程切换关键代码 */
asm volatile(
"pushl %%ebp\n\t" /* 把当前进程的ebp保存*/
"movl %%esp,%0\n\t" /* 把当前进程的esp赋值到sp中保存下来*/
"movl %2,%%esp\n\t" /* 把下一个进程的sp放到esp中*/
"movl $1f,%1\n\t" /* 把eip保存起来,$1f指接下来的标号1:的位置*/
"pushl %3\n\t" /*把下一个进程的eip保存起来*/
"ret\n\t" /* 还原eip */
"1:\t" /* 标号1,下一进程从此开始 */
"popl %%ebp\n\t"
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);
my_current_task = next;
printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
}
(2).进程是一个新进程,还从未执行过
/*myinterrupt.c*/
/*这段代码是当进程从未执行过时,所执行的动作,即启动一个进程
next->state = 0; /* 首先要把进程置为运行时状态,作为当前正在执行的进程 */
my_current_task = next;
printk(KERN_NOTICE ">>>switch %d to %d<<<\n",prev->pid,next->pid);
/* 进程切换时的提示,从当前进程切换至下一进程*/
asm volatile( //混合编程
"pushl %%ebp\n\t" /* 保存ebp */
"movl %%esp,%0\n\t" /* 保存esp */
"movl %2,%%esp\n\t" /* 将下一进程的sp存入esp */
"movl %2,%%ebp\n\t" /* 将下一进程的bp存入ebp,因为栈空,所以esp和ebp指向同一位置 */
"movl $1f,%1\n\t" /* 保存eip */
"pushl %3\n\t" /*保存当前进程入口 */
"ret\n\t" /* 还原eip */
: "=m" (prev->thread.sp),"=m" (prev->thread.ip)
: "m" (next->thread.sp),"m" (next->thread.ip)
);
实验截图

20135302魏静静Linux内核分析第二周学习总结的更多相关文章
- LINUX内核分析第二周学习总结——操作系统是如何工作的
LINUX内核分析第二周学习总结——操作系统是如何工作的 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...
- Linux内核分析第二周学习笔记
linux内核分析第二周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...
- Linux内核分析第二周学习博客——完成一个简单的时间片轮转多道程序内核代码
Linux内核分析第二周学习博客 本周,通过实现一个简单的操作系统内核,我大致了解了操作系统运行的过程. 实验主要步骤如下: 代码分析: void my_process(void) { int i = ...
- Linux内核分析第二周学习总结:操作系统是如何工作的?
韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.函数调用堆栈 ...
- Linux内核分析——第二周学习笔记
20135313吴子怡.北京电子科技学院 chapter 1 知识点梳理 (一)计算机是如何工作的?(总结)——三个法宝 ①存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: ②函数调用堆栈,高 ...
- 三20135320赵瀚青LINUX内核分析第二周学习笔记
赵瀚青原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.计算机的三个法宝 存储程 ...
- Linux内核分析——第二周学习笔记20135308
第二周 操作系统是如何工作的 第一节 函数调用堆栈 存储程序计算机:是所有计算机基础的框架 堆栈:计算机中基础的部分,在计算机只有机器语言.汇编语言时,就有了堆栈.堆栈机制是高级语言可以运行的基础. ...
- linux内核分析第二周
网易云课堂linux内核分析第二周 20135103 王海宁 <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...
- Linux内核分析第二周--操作系统是如何工作的
Linux内核分析第二周--操作系统是如何工作的 李雪琦 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course ...
随机推荐
- 牛客网_Wannafly模拟赛1
A.矩阵 题目链接:https://www.nowcoder.com/acm/contest/submit/f8363c912a4c48a28b80f47e7102b6b8?ACMContestId= ...
- mysql备份总结
w汇总对比. mysqldump -u user -p wdbname > /www/wbak.sql pwd CREATE TABLE wbak_w_02071349 LIKE w; INSE ...
- [genome shell]标题栏优化
参考地址:https://wiki.archlinux.org/index.php/GNOME_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#.E4.BB.8E.E5. ...
- 关于spring的applicationContext.xml配置文件的ref和value之自我想法
今天在做SSH的一个项目的时候,因为需要定时操作,所以就再sping里面加入了一个quartz的小定时框架,结果在运行时候,发生了一个小bug. Caused by: org.springframew ...
- 出现unmapped spring configuration files found
intell idea启动出现unmapped spring configuration files found提示. 把spring里面的内容都打勾.
- 6.2 - BBS + BLOG系统
一.简介 博客系统开发: 1.注册,登录,首页 2.个人站点,分组:(分类,标签,归档)3.文章详细页4.点赞,踩灭5.评论楼,评论树6.后台管理,发布文章,文件上传7.BeautifulSoup8. ...
- PDO 指南
简介 前面咱已经见过MySQLi了,现在咱一起来看看PDO类.PDO是PHP Data Objects的缩写,它被描述为“在PHP中访问数据库的轻量级,兼容性的接口”.尽管它的名字不咋好听,但PDO是 ...
- Laravel 5.3 使用内置的 Auth 组件实现多用户认证功能
https://blog.csdn.net/kevinbai_cn/article/details/54341779 概述 在开发中,我们经常会遇到多种类型的用户的认证问题,比如后台的管理员和前台的普 ...
- GlusterFS部署
一.GlusterFS简介 PB级容量.高可用.读写性能.基于文件系统级别共享.分布式.无metadata(元数据)的存储方式. GlusterFS(GNU ClusterFile System)是一 ...
- UVA10954:Add All(优先队列)
题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68990#problem/O 题目需求:在数组中拿出两个数相加,再把结果放回数组中再 ...