printf函数实现

printf函数实现

ID:37895678

大小:40.00 KB

页数:10页

时间:2019-06-02

printf函数实现_第1页
printf函数实现_第2页
printf函数实现_第3页
printf函数实现_第4页
printf函数实现_第5页
资源描述:

《printf函数实现》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、intprintf(constchar*fmt,...)  {  inti;  charbuf[256];    va_listarg=(va_list)((char*)(&fmt)+4);  i=vsprintf(buf,fmt,arg);  write(buf,i);    returni;  }  代码位置:D:/~/funny/kernel/printf.c    在形参列表里有这么一个token:...  这个是可变形参的一种写法。  当传递参数的个数不确定时,就可以用这种方式来表示。  很显然,我们需要一

2、种方法,来让函数体可以知道具体调用时参数的个数。    先来看printf函数的内容:    这句:    va_listarg=(va_list)((char*)(&fmt)+4);    va_list的定义:  typedefchar*va_list  这说明它是一个字符指针。  其中的:(char*)(&fmt)+4)表示的是...中的第一个参数。  如果不懂,我再慢慢的解释:  C语言中,参数压栈的方向是从右往左。  也就是说,当调用printf函数的适合,先是最右边的参数入栈。  fmt是一个指针,这个指

3、针指向第一个const参数(constchar*fmt)中的第一个元素。  fmt也是个变量,它的位置,是在栈上分配的,它也有地址。  对于一个char*类型的变量,它入栈的是指针,而不是这个char*型变量。  换句话说:  你sizeof(p)(p是一个指针,假设p=&i,i为任何类型的变量都可以)  得到的都是一个固定的值。(我的计算机中都是得到的4)  当然,我还要补充的一点是:栈是从高地址向低地址方向增长的。  ok!  现在我想你该明白了:为什么说(char*)(&fmt)+4)表示的是...中的第一个参

4、数的地址。    下面我们来看看下一句:  i=vsprintf(buf,fmt,arg);    让我们来看看vsprintf(buf,fmt,arg)是什么函数。    intvsprintf(char*buf,constchar*fmt,va_listargs)  {  char*p;  chartmp[256];  va_listp_next_arg=args;    for(p=buf;*fmt;fmt++){  if(*fmt!='%'){  *p++=*fmt;  continue;  }    fmt

5、++;    switch(*fmt){  case'x':  itoa(tmp,*((int*)p_next_arg));  strcpy(p,tmp);  p_next_arg+=4;  p+=strlen(tmp);  break;  case's':  break;  default:  break;  }  }    return(p-buf);  }    我们还是先不看看它的具体内容。  想想printf要左什么吧  它接受一个格式化的命令,并把指定的匹配的参数格式化输出。    ok,看看i=vspr

6、intf(buf,fmt,arg);  vsprintf返回的是一个长度,我想你已经猜到了:是的,返回的是要打印出来的字符串的长度  其实看看printf中后面的一句:write(buf,i);你也该猜出来了。  write,顾名思义:写操作,把buf中的i个元素的值写到终端。    所以说:vsprintf的作用就是格式化。它接受确定输出格式的格式字符串fmt。用格式字符串对个数变化的参数进行格式化,产生格式化输出。  我代码中的vsprintf只实现了对16进制的格式化。    你只要明白vsprintf的功能是

7、什么,就会很容易弄懂上面的代码。    下面的write(buf,i);的实现就有点复杂了    如果你是os,一个用户程序需要你打印一些数据。很显然:打印的最底层操作肯定和硬件有关。  所以你就必须得对程序的权限进行一些限制:    让我们假设个情景:  一个应用程序对你说:os先生,我需要把存在buf中的i个数据打印出来,可以帮我么?  os说:好的,咱俩谁跟谁,没问题啦!把buf给我吧。    然后,os就把buf拿过来。交给自己的小弟(和硬件操作的函数)来完成。  只好通知这个应用程序:兄弟,你的事我办的妥妥

8、当当!(os果然大大的狡猾^_^)  这样应用程序就不会取得一些超级权限,防止它做一些违法的事。(安全啊安全)    让我们追踪下write吧:    write:  moveax,_NR_write  movebx,[esp+4]  movecx,[esp+8]  intINT_VECTOR_SYS_CALL    位置:d:~/kernel

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。