标签:
几个重要的汇编指令:push、pop、call、ret
1、pushl %eax 把eax压栈到堆栈栈底 即首先把esp减4 esp表示堆栈栈顶 ebp表示堆栈基址 2、popl %eax 把eax从堆栈栈顶取32位,放在寄存器eax中 即首先把栈顶esp的数值放在eax中,再把栈顶加4 3、call 0x12345 调用该地址 即将当前的eip(当前CPU执行命令的指针)压栈,赋给eip一个新值(CPU下一条执行的指令) 4、ret 即将call时保存的eip还原到eip寄存器,return call之前的那条指令 eip(*)这个*指程序员不能直接修改eip
•cs : eip:总是指向下一条的指令地址 • 顺序执行:总是指向地址连续的下一条指令 • 跳转/分支:执行这样的指令的时候,cs : eip的值会 根据程序需要被修改 • call:将当前cs : eip的值压入栈顶,cs : eip指向被 调用函数的入口地址 • ret:从栈顶弹出原来保存在这里的cs : eip的值,放 入cs : eip中
1、中断上下文的切换:保存现场和恢复现场
2、进程上下文的切换
输入以下命令
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -S -s
-S表示:在CPU初始化之前,冻结CPU
-s表示在:1234端口上创建一个tcp接口
CPU每条指令的读取都是通过cs:eip(代码段选择寄存器:偏移量寄存器)这两个寄存器,由硬件完成判断。
内核态时,cs与eip的值可以访问任意地址
用户态时,cs与eip只可以访问0x00000000—0xbfffffff的地址空间
一层皮:API
二层皮:中断向量对应的中断服务程序
三层皮:系统调用对应的很多不同种类的服务程序
整个系统调用过程中,时间很重要。
以system_call为例,int 0x80指令与systemcall是通过中断向量联系起来的,而API和对应的sys是通过系统调用号联系起来的
用户态时,系统调用xyz()使用int 0x80,它对应调用system_call
右边的处理过程(汇编代码)非常重要,通过系统调用号匹配起来
分析system_call中断处理过程
执行rm menu -rf,强制删除原有的menu文件夹,使用git命令更新menu代码至最新版。
在test.c中添加C函数、汇编函数
make rootfs,输入help,可以看到qemu中增加了之前添加的命令
进入gdb调试
设置断点
c运行
单步执行
0号进程是手工写入它的进程描述符数据,1号进程的创建是复制了0号进程的PCB,根据1号进程的需要,修改PID,加载一个init可执行程序。
fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。
Linux通过复制父进程来创建一个新进程,那么这就给我们理解这一个过程提供一个想象的框架:
C代码—>预处理—>汇编代码—>目标代码—>可执行文件
进程分类
Linux的调度基于分时和优先级。
next = pick_next_task(rq, prev);//进程调度算法都封装这个函数内部
context_switch(rq, prev, next);//进程上下文切换
switch_to利用了prev和next两个参数:prev指向当前进程,next指向被调度的进程
标签:
原文地址:http://www.cnblogs.com/bonjourvivi/p/5414954.html