Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1879603
  • 博文数量: 333
  • 博客积分: 10791
  • 博客等级: 上将
  • 技术积分: 4314
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-08 07:39
文章分类

全部博文(333)

文章存档

2015年(1)

2011年(116)

2010年(187)

2009年(25)

2008年(3)

2007年(1)

分类:

2009-03-15 23:33:23

简单介绍:什么是EIP、ESP、EBP

堆栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表。
允许插入或删除操作的一端称为栈顶,另一端称为栈底,对堆栈的插入和删除操作被称入栈出栈
有一组CPU指令可以实现对进程的内存实现堆栈访问。其中,POP指令实现出栈操作,PUSH指令实现入栈操作。
CPU的ESP寄存器存放当前线程的栈顶指针
EBP寄存器中保存当前线程的栈底指针
CPU的EIP寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。

实现原理:C函数调用时,首先将参数push入栈,然后push返回地址,接着将原来的EBP push入栈,然后将ESP的值赋给EBP,令ESP指向新的栈顶。而函数返回时,会将EBP的值赋予ESP,然后pop出原来的EBP的值赋予EBP指针。 更详细准确的信息请参考《linux内核完全剖析》一书中的"3.4.1 C函数调用机制"。
详细实现:

int
mon_backtrace(int argc, char **argv, struct Trapframe *tf)
{
 // Your code here.
 unsigned int ebp;
   unsigned int eip;
   unsigned int args[5];
   unsigned int i;

   ebp = read_ebp();
   cprintf("Stack backtrace:\n");
   do {
     eip = *((unsigned int*)(ebp + 4));
      for(i=0; i<5; i++)
         args[i] = *((unsigned int*) (ebp + 8 + 4*i));

      cprintf("  ebp %08x  eip %08x  args %08x %08x %08x %08x %08x\n",
       ebp, eip, args[0], args[1], args[2], args[3], args[4]);


     ebp = *((unsigned int *)ebp);
   } while(ebp != 0);


 return 0;
}

将此功能添加到monitor中,只需修改文件kern/monitor.c, 添加以下代码到变量struct Command commands[]中既可:
{ "mon_backtrace", "Backtrace functions call chain", mon_backtrace },

阅读(3828) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~