一个让printf不正常工作的例子 - 已解决

话说今天做了一个课程实验,但是出了一点点问题,问题在于突然printf出现无法正常输出了..经过一翻小研究,发现了导致printf不正常的代码...但是不懂这段代码对应的那段软中断处理代码具体做了什么..所以没有继续研究下去..今天记录在此,希望在不久的将来能够查明是什么原因...
 
 
/* 一个让printf不正常工作的例子 */

/* 如果程序使用下面的一段汇编代码来实现返回操作系统,则printf向终端输出的字符流中,终端只显示字符流中最后一个\n符号前面的字符。
 * 如果字符流没有\n,则所在字符都不能正常显示出来。
 * 比如返回操作系统前,printf总共向终端输出如下字符流:
 *
 * XXXXXXXXXXX\n
 * Xxxxxxxxxxxxxxxx\n\xxxxxx
 * xxxxxxxxxxxxxx\n
 * YYYYYYYYYYYYYYYyyyyyy
 *
 * 这样最后一符的所有Y都不会显示出来,事实上是最后一个\n后面的所有字符都不会在终端前面显示出来。
 *
 * 测试环境
 * gcc版本:
 *	gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 
 * ubuntu版本:
 * 	Linux abee-lisa-linux 2.6.35-32-generic #64-Ubuntu SMP Mon Jan 2 23:31:33 UTC 2012 i686 GNU/Linux
 *
 * 目前暂不知道到底这个软中断具体做了什么,so..留着有待研究咯.
 */

/* 哪个大哥大姐知道这是怎么回事的,望指点指点迷津呀。 ^_^ */


#include <stdio.h>

int main()
{
	printf("this is a string with \\n \n");
	printf("this is a string with \\n \n");

	printf("this is a string without \\n");
	/* 直接内联汇编 */
	__asm__("movl $1,%eax\n \
		 movl $0,%ebx\n \
		 int $0x80");		//是返回操作系统了,并以返回值0返回。但是却影响了终端的显示。

	//exit(0);		/* 真正的exit(0); */
	return 0;
}

/* 正常的输出应该是:
 * this is a string with \n 
 * this is a string with \n
 * this is a string without \n
 * 但是,如果采用不同的返回操作系统的方式,結果是不一样的。
 */


原因解释(2014-11-01):
这里有个背景:针对终端设置,printf输出缓冲模式是行模式,即遇到\n就会真正flush到终端上,否则先缓存,直到缓冲区满了才flush到终端上。
这里内联汇编中的代码实现的是返回操作系统,注意这里是直接由汇编代码返回,因此隐藏了一个程序在正常返回操作系统之前所隐藏的逻辑,如关闭文件、清空缓存区等等。
这里最后一个\n后面的没有输出的原因就是少了正常退出所做的清空缓存逻辑,这段代码和_exit(0)功能一样(注意是_exit(),需包含unistd.h)。
 
 
对于exit(0)和return 0;这两个方式其实都含有清空缓存区的逻辑,因此在返回操作系统前会正常见到预期输出的数据。
 

你可能感兴趣的:(一个让printf不正常工作的例子 - 已解决)