标题:[原创]深入讲解main()返回值问题
只看楼主
china25qd
Rank: 1
等 级:新手上路
帖 子:161
专家分:0
注 册:2007-9-6
得分:0 
以下是引用野比在2007-9-29 19:22:23的发言:
有个地方:程序结束后,返回到command中
这里没有讲好,是这样的,程序结束后,CS:IP指向command.com进入用户程序前的下一条语句(最后一条语句是“然后设置CPU的CS:IP指向程序的第一条指令”)
此时,command.com从stack里弹出(pop)2或4字节的内容,这些内容就是用户程序的返回值。
没有返回值就是0,所以编写正常的main就算是void型的也可以照常退回dos。

再好好修改扩展一下,写好点加精。

现在就能加精了


抱膝怀天下 闲坐观四海
2007-10-04 23:55
秀才
Rank: 1
等 级:新手上路
帖 子:56
专家分:0
注 册:2007-9-30
得分:0 
回复:(郭芙蓉)秀才过来看你写的什么狗屁东西:[cod...

芙妹,我那是无心之错。子曾经曰过:有心为善虽善不赏,无心之过虽恶不罚。

我等下再回个帖子来弥补过错。

PS:楼上的那位你不知道CS:IP是楼主糊弄人的吗?现在PC普及在32位上,指令指针已经是EIP了,windows也用平坦内存模式,段寄存器的概念已经模糊了。


2007-10-06 13:33
秀才
Rank: 1
等 级:新手上路
帖 子:56
专家分:0
注 册:2007-9-30
得分:0 



子曾经曰过:源码在前,了无秘密.
我15楼已经给出了一个简单的shell实现,不过只是分析了执行程序时进程的活动,main函数的调用和返回没有详细说,现在尽我所知尽可能的说详细些,以UNIX系统为例:

当系统执行c程序时是通过一个exec调用,在这个调用中进入main之前还有个特殊的启动routine,该routine是进程中程序的入口地址,工作是从OS内核中取得命令行参数和环境变量,打开stdin,sdtout,stderr三个文件流,为进入main做准备。之后的工作就是调用main了,main返回之后该进程立即调用exit函数,将main的返回值传递到OS内核。由于该routine通常用汇编写,这里给出等价的c代码:exit(main(argc,argv));exit函数会执行标准IO库的清理关闭操作:为所有打开流调用fclose函数,让所有缓冲的数据都被冲洗,写到文件中。

exit使用一个整形参数(shell提供从内核获取该值的功能),若main执行一个无返回值的return语句或main没有声明返回值为整形,该进程的终止状态是未定义的,但若main的返回值声明为整形但执行到最后一句时没有显式的return或exit()一个整数,那么该进程的终止状态是0。这种处理是C99规定的,C99标准之前没有显式返回的进程的终止状态也是未定义的。见下例:


#include<stdio.h>
main()
{
printf(\"hello.world\n\");
}

编译该程序后运行可以看到终止码是随机的,不同的系统上编译该程序会有不同的结果,取决于main返回时栈和寄存器的内容:

$ cc hello.c
$ ./a.out
hello,world
$ echo $?
13

如果启用C99编译器扩展就可以看到终止码改变了:

$ cc -std=c99 hello.c
hello.c:c4:warning:return type defaults to 'int'
$ ./a.out
hello,world
$ echo $?
0

上面几段差不多说清了main的一生一世,进入到退出,不过还是比较杂乱,看的让人有点头晕,那个简易的shell模型启动应用程序的过程中执行流程在用户态和内核态之间来回穿梭,下面给个图说明:

用户态 【shell】----- --【新的shell进程】-- --【执行main的进程】--
↓fork ↑ ↓exec ↑ ↓return或exit调用
------------------------------------------------------------------------------------------------------------------
↓ ↑ ↓ ↑ ↓
内核态 内核fork服务------- 内核exec服务----- 获取终止码撤销进程服务


OVER,以我目前的功力只能分析到这一层了,我师弟已于前日退出论坛,我在这里也没意思,回去闭关修炼去也。
PS:那些个不学无术的最好找个CS的本科专业认真念四年,不才在CS&T专业混了四年才把一只脚伸进CS的大门。还有那个叫栖柏的小P孩不要再灌水了,回去老实念书去。

================================================================================================================
Bibliography
Addison Wesley,Advanced Programming in the UNIX Environment: Second Edition
By W. Richard Stevens, Stephen A. Rago
Person Education,Modern Operating Systems:Second Edition
By Andrew S.Tanenbaum



2007-10-06 13:48
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
得分:0 
再次鼓掌......

谢谢又给我补充了些"营养元素"

ありがと



[此贴子已经被作者于2007-10-6 16:39:47编辑过]


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-10-06 16:25
栖柏
Rank: 2
等 级:论坛游民
威 望:3
帖 子:1103
专家分:17
注 册:2007-8-23
得分:0 
这帖精彩!

You have lots more to work on! Never give up!c language!
2007-10-06 19:00
aipb2007
Rank: 8Rank: 8
来 自:CQU
等 级:贵宾
威 望:40
帖 子:2879
专家分:7
注 册:2007-3-18
得分:0 
回复:(秀才) 子曾经曰过:源码在前,了无秘密. ...
精华

Fight  to win  or  die...
2007-10-06 19:11
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
得分:0 
我又有了新的想法,但还没得到答案,所以还不想补充到原贴中,

新的想法如下:

现在可以基本肯定一点,main()函数最后结束之后,要返回操作系统,

那么CPU会对相关寄存器做些恢复操作,

但是到底做了哪些工作,目前我实在不知道,

我觉的要清楚的解释其来龙去脉可能要涉及到内核级的知识,

所以我希望内核级的超级大师点拨我一下.

不懂的就不要乱发贴 瞎 嚷 嚷 了!

[此贴子已经被作者于2007-10-8 21:36:29编辑过]


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-10-08 21:34
sdz
Rank: 1
等 级:新手上路
帖 子:15
专家分:0
注 册:2007-10-8
得分:0 
关注..

工控控件 报表控件 图形控件 音视频控件..
2007-10-09 20:01
mbstorm
Rank: 1
等 级:新手上路
帖 子:166
专家分:0
注 册:2008-10-31
得分:0 
怎么看不到 作者被禁止或删除 内容自动屏蔽
2008-11-01 13:30
mbstorm
Rank: 1
等 级:新手上路
帖 子:166
专家分:0
注 册:2008-10-31
得分:0 
怎么没有啊
2008-11-03 21:46



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-174080-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.337452 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved