printf和标准输出

发布时间:2021-10-22 00:14:19

转载自:http://blog.chinaunix.net/uid-21067667-id-447689.html


???上次写到main函数的参数传递。现在继续往下进行。最*忙实验室的事情,看了一周的文章,也没啥进展,周末写点技术贴,放松一下:-)


??进入main函数后,就要调用printf(“Hello World!”);了,顺便将C语言参数传递提一下。字符串”Hello World!”编译器是当作字符串常量来处理的,虽然printf是在main内部调用,但”Hello World!”可不是放在main的栈中,字符串常量至少是放到.data段的,准确说是放在只读数据段.rodata,这个我在工作站上验证了一把。假如编辑的文件名是hello.c,首先编译生成elf格式二进制文件gcc hello.c -o hello然后用命令objdump -s hello(-s参数会将所有段信息dump出来),你会看到”Hello World!”位于.rodata段。


??? printf()是个标准C库函数,虽然功能简单,但实现起来却不容易。这是个和*台相关的函数。在pc上,printf输出是输出到终端屏幕,在嵌入式设备上,一般printf()是输出到串口。同是调用printf(),最终输出的设备却不同,从直觉的肯定是感觉printf()底层和*台是相关的。那么printf()是怎样实现的呢?


??? 可以看一下C库程序的代码,这里以uClibc为例。

??? 跟进vfprintf()函数看,里面是复杂的参数处理,因为printf()的参数形式很灵活,所以在vfprintf()里面要对传进来的参数进行解析处理,形成最终的输出格式。有兴趣的可以看一下,借助这个可以让你在一个没有操作系统的*台上实现你自己的printf()函数。这样你在裸机上调程序时输出调试信息就更方便些(实际上uClinux的printk就是这么干的)。


??? vfprintf()在参数处理之后,就是输出了,输出调用的是putc(),进入putc()然后再跟进几层函数,发现调用了linux系统调用write()。呵呵,是的,输出就是借助操作系统代码完成的。在write之前所有的代码都是C库的代码,可以说是和*台无关的。

??? Linux系统调用针对不同*台有不同的实现方式。这个以后再讲。调用write()后,进入内核空间,首先来到的就是sys_write(),这个函数代码位于fs/read_write.c中。

??? 有关linux的设备驱动有很多书介绍,整个驱动的结构很复杂,我这里也没必要提了。至于终端设备怎样挂在驱动队列里面,怎么根据标准输出的描述符找到相应的驱动结构,有兴趣的请查阅相关资料。

相关文档

  • 应急钱包怎么用?应急钱包使用教程
  • 蓝桥杯(Java) 入门训练 Fibonacci数列
  • php 控制 打印机 打印尺寸_强强联手,铂力特大尺寸金属3D打印机BLTS450落户西安航天...
  • php数组位运算,php 位运算
  • 在生日宴会上的答谢词
  • 红米k30s呼吸灯不亮
  • 吃什么去痘痘效果最好食疗完美对付顽固痘痘
  • 九大必看的古装电视剧 陈情令与琅琊榜占据一二名
  • 泰迪狗不能吃什么东西小心吃了这些食物泰迪说byebye
  • 三大框架的原理和优缺点
  • variant每个成员必赋值_「事件驱动架构」Kafka再平衡协议:静态成员和增量合作再平衡...
  • “五档成交剩余撤销”和“五档成交剩余转限”分别代表什么意思
  • 关于Invalid prop: type check failed for prop "row". Expected String, got Object.的问题及审查办法
  • 致全镇人民的公开信
  • 餐厅宣传单模板图片的展示
  • Rust语言正在兴起,Java、Python、C的末日来临?
  • 20个激发灵感电商网站设计,赶紧Mark起来!
  • ESP8266从零学起第三课检测温湿度DHT11
  • RMI规范(10)
  • 什么是报关员
  • 欢度中秋节的黑板报内容
  • 厂房租赁合同书模板
  • 输卵管造影后出血几天,输卵管造影流血要几天,输卵管造影出血多久
  • 道歉时哄男友开心说的话语
  • 《战长沙》观后感
  • 周公解梦梦见做手术的预兆
  • 《走过谁的城》读后感1600字
  • 什么泡水喝养肝护肝呢
  • 金丝鱼怎么做好吃
  • 公路竣工庆典讲话3篇精选多篇
  • 猜你喜欢