新闻中心

EEPW首页>嵌入式系统>设计应用> 系统调试信息的显示方法

系统调试信息的显示方法

作者: 时间:2012-03-07 来源:网络 收藏

表2 函数调用时的参数在堆栈中的存储情况(X86环境)

表2说明了两个问题:第一个问题是,每个参数在堆栈中的存储长度和参数的类型有关。对于指针类型参数,参数长度和编译模式有关:大模式下,地址包括段地址和偏移地址,共4字节;而小模式下,地址只有段内偏移,占2字节。第二个问题是,如果知道其中的一个参数地址和参数的类型,则可以得到任意参数的数值,并不需要知道参数的名称。比如在函数fun()中,可用以下代码各个参数的内容:

  void fun(char *str,int i,float *a)

  {

  void *p

  p=str;

  printf(str=%s,str); p=(char **)p+1;

  printf(i=%d ((int*)p));p=(int *)p+1;

  printf(i=%d *((float *)p));

  }

3 PC机上的printf()函数的设计实现

现在,可以编写自己的printf()函数了。以下给出TC20编译环境下的具体实现代码,在其他环境下,可以根据该原理进行移植。也可以按位二进制数。对于其他类型,读者可以根据需要增删。

在实际应用中,可以修改其中的putchar()函数,将字符发到串口,就可以达到上述目的了。这里我们编写的函数还增加了数字的二进制,这对于很多位域应用是很有用处的。

  /*printf()函数的实现代码,为和库函数区别,特在各函数前增加前缀“my”*/

  void myprintf(char *fmt,…)

  {

  void *p;

  char ch;

  p=fmt;p=(char**)p+1;/*指向堆栈中的下一个参数*/

  while(1){

  while((ch=*fmt++)!='%'{/*读入格式字符串*/

  if(ch= ='0')return;

  putchar(ch);

  };

  ch=*fmt++;

  switch(ch){ /*格式字符分析*/

  /*因为字符参数传递时也转换成整形参数传递,故同样处理*/

  case 'c':

  case'd':

  case'x':

  case'0':

  case'b':

  if(ch= ='c')myputchar(*(int *)p));

  if(ch= ='d')myprintn(*((int *)p),10);

  if(ch= ='x')myprintn(*((int *)p),16);

  if(ch= ='o')myprintn(*((int *)p),8);

  if(ch= ='b')myprintn(*((int *)p),2);

  p=(int)p+1; /*指针移动*/

  break;

  case's':

  myputs(*((char **)p));

  p=(char **)p+1; /*指针移动*/

  break;

  default;

  };

  }

  }



评论


相关推荐

技术专区

关闭