关于C程序的运行环境(初始化?)的问题.

YoziDream 2005-06-30 02:09:53
刚刚了解到C Runtime Library的一些知识,认识到通常以为的main不是真正的入口
而是由C Runtime调用的,runtime需要做一些初始化的工作。程序结束时要由runtime
来做些清理工作,应该可以(?)说runtime提供了C程序的运行环境吧?

我的问题是,
(1)如果是runtime提供了这个环境,runtime与操作系统的关系是什么呢?
不是说操作系统提供了程序运行的服务吗?
(2)runtime到底干了些什么,比如说初始化吧,看网上一些文章说做了一些
堆栈啊,堆啊的初始设置?我知道函数的参数是由堆栈来传递的,可是函数
编译好了以后不就是已经包含了使用堆栈的指令了吗?runtime设置堆栈设置些啥呢?
可以给解释一下初始化的那个runtime函数吗?现在还看不懂。
(3)x86下,C写成的程序,对寄存器使用有什么约定吗?我看“hello,world!"的反汇编代码
看到那些代码像天书一样,硬是和c程序对不上钩。我想是和不知道每一个寄存器被用来
干了解的缘故?

谢谢!
...全文
553 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Flood1984 2005-07-20
  • 打赏
  • 举报
回复
(3)x86下,C写成的程序,对寄存器使用有什么约定吗?我看“hello,w

orld!"的反汇编代码
看到那些代码像天书一样,硬是和c程序对不上钩。我想是和不知道每

一个寄存器被用来
干了解的缘故?
//有一些寄存器确实是有专门用途的,比如你在每个函数的一开始就会看

到:
push ebp //就ebp的值保存
mov ebp,esp//用ebp保存当前的栈顶指针
sub esp,40h//移动当前的栈顶指会针,这样就为局部变量开

辟了空间(esp-ebp的这一段内存).
在函数结束时有:
mov esp,ebp//还原esp的值,这样局部变量的空间就被释放.
pop ebp//还原ebp的值
YoziDream 2005-07-06
  • 打赏
  • 举报
回复
仍没有解决
有人能够提供相关资料也好呀
YoziDream 2005-07-01
  • 打赏
  • 举报
回复
JohnTitor(努力学习):
你给的这个代码就是 startup code?

可不可以略作解释,看起来好吃力!谢谢
imya 2005-07-01
  • 打赏
  • 举报
回复
不会,关注学习ing
SereinLi 2005-07-01
  • 打赏
  • 举报
回复
偶不太会,顶下.
楼上的代码好长呀!
login__whf 2005-06-30
  • 打赏
  • 举报
回复
mark
JohnTitor 2005-06-30
  • 打赏
  • 举报
回复
自己看代码:
{
int initret;
int mainret;
OSVERSIONINFOA *posvi;
int managedapp;
#ifdef _WINMAIN_
_TUCHAR *lpszCommandLine;
STARTUPINFO StartupInfo;
#endif /* _WINMAIN_ */
/*
* Dynamically allocate the OSVERSIONINFOA buffer, so we avoid
* triggering the /GS buffer overrun detection. That can't be
* used here, since the guard cookie isn't available until we
* initialize it from here!
*/
posvi = (OSVERSIONINFOA *)_alloca(sizeof(OSVERSIONINFOA));

/*
* Get the full Win32 version
*/
posvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
(void)GetVersionExA(posvi);

_osplatform = posvi->dwPlatformId;
_winmajor = posvi->dwMajorVersion;
_winminor = posvi->dwMinorVersion;

/*
* The somewhat bizarre calculations of _osver and _winver are
* required for backward compatibility (used to use GetVersion)
*/
_osver = (posvi->dwBuildNumber) & 0x07fff;
if ( _osplatform != VER_PLATFORM_WIN32_NT )
_osver |= 0x08000;
_winver = (_winmajor << 8) + _winminor;

/*
* Determine if this is a managed application
*/
managedapp = check_managed_app();

#ifdef _MT
if ( !_heap_init(1) ) /* initialize heap */
#else /* _MT */
if ( !_heap_init(0) ) /* initialize heap */
#endif /* _MT */
fast_error_exit(_RT_HEAPINIT); /* write message and die */

#ifdef _MT
if( !_mtinit() ) /* initialize multi-thread */
fast_error_exit(_RT_THREAD); /* write message and die */
#endif /* _MT */

/*
* Initialize the Runtime Checks stuff
*/
#ifdef _RTC
_RTC_Initialize();
#endif /* _RTC */
/*
* Guard the remainder of the initialization code and the call
* to user's main, or WinMain, function in a __try/__except
* statement.
*/

__try {

if ( _ioinit() < 0 ) /* initialize lowio */
_amsg_exit(_RT_LOWIOINIT);

#ifdef WPRFLAG
/* get wide cmd line info */
_wcmdln = (wchar_t *)__crtGetCommandLineW();

/* get wide environ info */
_wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();

if ( _wsetargv() < 0 )
_amsg_exit(_RT_SPACEARG);
if ( _wsetenvp() < 0 )
_amsg_exit(_RT_SPACEENV);
#else /* WPRFLAG */
/* get cmd line info */
_acmdln = (char *)GetCommandLineA();

/* get environ info */
_aenvptr = (char *)__crtGetEnvironmentStringsA();

if ( _setargv() < 0 )
_amsg_exit(_RT_SPACEARG);
if ( _setenvp() < 0 )
_amsg_exit(_RT_SPACEENV);
#endif /* WPRFLAG */

initret = _cinit(TRUE); /* do C data initialize */
if (initret != 0)
_amsg_exit(initret);

#ifdef _WINMAIN_

StartupInfo.dwFlags = 0;
GetStartupInfo( &StartupInfo );

#ifdef WPRFLAG
lpszCommandLine = _wwincmdln();
mainret = wWinMain(
#else /* WPRFLAG */
lpszCommandLine = _wincmdln();
mainret = WinMain(
#endif /* WPRFLAG */
GetModuleHandleA(NULL),
NULL,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
? StartupInfo.wShowWindow
: SW_SHOWDEFAULT
);
#else /* _WINMAIN_ */

#ifdef WPRFLAG
__winitenv = _wenviron;
mainret = wmain(__argc, __wargv, _wenviron);
#else /* WPRFLAG */
__initenv = _environ;
mainret = main(__argc, __argv, _environ);
#endif /* WPRFLAG */

#endif /* _WINMAIN_ */

if ( !managedapp )
exit(mainret);

_cexit();

}
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
{
/*
* Should never reach here
*/

mainret = GetExceptionCode();

if ( !managedapp )
_exit(mainret);

_c_exit();

} /* end of try - except */

return mainret;
}
jsjjms 2005-06-30
  • 打赏
  • 举报
回复
关注.............
jixingzhong 2005-06-30
  • 打赏
  • 举报
回复
x86下,C写成的程序,对寄存器使用有什么约定吗


只有 局部变量、形式参数

能够设置为 寄存器 变量,使用寄存器!!


而且数量有限!!

(多了的时候,也不讳出错,只是自动的恢复为auto变量!!)
jixingzhong 2005-06-30
  • 打赏
  • 举报
回复
你可以这么理解:

系统在最底层,上面是RUNTIME(名字就是运行期环境的意思!!)

而我们调试的程序是在最上层!!


程序呢,要分很多部分,RUNTIME的工作之一(涉及你说的内容)就是分配内存,

这个分配不是变量、函数什么的分配,

而是在内存中确定一些区域,如代码段,数据段,也就是你说的栈、和堆!

这不是我们在程序中的那些堆栈!!

千万不要混淆了(虽然,他们的原理是差不多的!!)



firstdreamer 2005-06-30
  • 打赏
  • 举报
回复
mark!
popcom 2005-06-30
  • 打赏
  • 举报
回复
我不会,我帮你顶
YoziDream 2005-06-30
  • 打赏
  • 举报
回复
"系统在最底层,上面是RUNTIME(名字就是运行期环境的意思!!)

而我们调试的程序是在最上层!!"

可是我想是不是与具体环境有关呢?比如用C语言写操作系统的时候,这个时候"操作系统程序"使用了
runtime的服务吗?再比如没有操作系统的环境,单片机里面的C51,用C语言写程序,可是那里一般情况下是没有操作系统.

或者我这个问题不应该问成与操作系统有什么关系,而是runtime为C程序具体都提供了
那些服务,这些服务是如何提供的?

也不知道我这样想对不对.
aSalt 2005-06-30
  • 打赏
  • 举报
回复
强烈UP

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧