Hello Word 详解:
include:
目标文件替换为当前行。复制粘贴头文件源代码。
< >:
表示先去坏境变量目录找头文件,如果找不到在到当前源码目录
“ ”:
表示先去当前源代码目录下寻找头文件,在到环境变量目录下找头文件。
main:
用户入口函数(mainCRTStartup: 系统入口)
mainCRTStartup 函数简介:
1 /***
2 *crt0.c - C runtime initialization routine
3 *
4 * Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 * This the actual startup routine for apps. It calls the user's main
8 * routine [w]main() or [w]WinMain after performing C Run-Time Library
9 * initialization.
10 *
11 * (With ifdef's, this source file also provides the source code for
12 * wcrt0.c, the startup routine for console apps with wide characters,
13 * wincrt0.c, the startup routine for Windows apps, and wwincrt0.c,
14 * the startup routine for Windows apps with wide characters.)
15 *
16 *******************************************************************************/
17
18 #ifdef _WIN32
19
20 #ifndef CRTDLL
21
22 #include <cruntime.h>
23 #include <dos.h>
24 #include <internal.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <rterr.h>
28 #include <windows.h>
29 #include <awint.h>
30 #include <tchar.h>
31 #include <dbgint.h>
32
33 /*
34 * wWinMain is not yet defined in winbase.h. When it is, this should be
35 * removed.
36 */
37
38 int
39 WINAPI
40 wWinMain(
41 HINSTANCE hInstance,
42 HINSTANCE hPrevInstance,
43 LPWSTR lpCmdLine,
44 int nShowCmd
45 );
46
47 #ifdef WPRFLAG
48 _TUCHAR * __cdecl _wwincmdln(void);
49 #else /* WPRFLAG */
50 _TUCHAR * __cdecl _wincmdln(void);
51 #endif /* WPRFLAG */
52
53 /*
54 * command line, environment, and a few other globals
55 */
56
57 #ifdef WPRFLAG
58 wchar_t *_wcmdln; /* points to wide command line */
59 #else /* WPRFLAG */
60 char *_acmdln; /* points to command line */
61 #endif /* WPRFLAG */
62
63 char *_aenvptr = NULL; /* points to environment block */
64 wchar_t *_wenvptr = NULL; /* points to wide environment block */
65
66
67 void (__cdecl * _aexit_rtn)(int) = _exit; /* RT message return procedure */
68
69 static void __cdecl fast_error_exit(int); /* Error exit via ExitProcess */
70
71 /*
72 * _error_mode and _apptype, together, determine how error messages are
73 * written out.
74 */
75 int __error_mode = _OUT_TO_DEFAULT;
76 #ifdef _WINMAIN_
77 int __app_type = _GUI_APP;
78 #else /* _WINMAIN_ */
79 int __app_type = _CONSOLE_APP;
80 #endif /* _WINMAIN_ */
81
82
83 /***
84 *BaseProcessStartup(PVOID Peb)
85 *
86 *Purpose:
87 * This routine does the C runtime initialization, calls main(), and
88 * then exits. It never returns.
89 *
90 *Entry:
91 * PVOID Peb - pointer to Win32 Process Environment Block (not used)
92 *
93 *Exit:
94 * This function never returns.
95 *
96 *******************************************************************************/
97
98 #ifdef _WINMAIN_
99
100 #ifdef WPRFLAG
101 void wWinMainCRTStartup(
102 #else /* WPRFLAG */
103 void WinMainCRTStartup(
104 #endif /* WPRFLAG */
105
106 #else /* _WINMAIN_ */
107
108 #ifdef WPRFLAG
109 void wmainCRTStartup(
110 #else /* WPRFLAG */
111 void mainCRTStartup( // 获取当前运行平台的版本号
112 #endif /* WPRFLAG */
113
114 #endif /* _WINMAIN_ */
115 void
116 )
117
118 {
119 int mainret;
120
121 #ifdef _WINMAIN_
122 _TUCHAR *lpszCommandLine;
123 STARTUPINFO StartupInfo;
124 #endif /* _WINMAIN_ */
125
126 /*
127 * Get the full Win32 version
128 */
129 _osver = GetVersion();
130
131 _winminor = (_osver >> 8) & 0x00FF ;
132 _winmajor = _osver & 0x00FF ;
133 _winver = (_winmajor << 8) + _winminor;
134 _osver = (_osver >> 16) & 0x00FFFF ;
135
136 #ifdef _MT
137 if ( !_heap_init(1) ) /* initialize heap */
138 #else /* _MT */ //用于初始化堆空间
139 if ( !_heap_init(0) ) /* initialize heap */
140 #endif /* _MT */
141 fast_error_exit(_RT_HEAPINIT); /* write message and die */
142
143 #ifdef _MT
144 if( !_mtinit() ) /* initialize multi-thread */
145 fast_error_exit(_RT_THREAD); /* write message and die */
146 #endif /* _MT */
147
148 /*
149 * Guard the remainder of the initialization code and the call
150 * to user's main, or WinMain, function in a __try/__except
151 * statement.
152 */
153
154 __try {
155
156 _ioinit(); /* initialize lowio */
157
158 #ifdef WPRFLAG
159 /* get wide cmd line info */
160 _wcmdln = (wchar_t *)__crtGetCommandLineW();
161
162 /* get wide environ info */
163 _wenvptr = (wchar_t *)__crtGetEnvironmentStringsW();
164
165 _wsetargv();
166 _wsetenvp();
167 #else /* WPRFLAG */
168 /* get cmd line info */
169 _acmdln = (char *)GetCommandLineA(); //获取命令行参数信息的首地址
170
171 /* get environ info */
172 _aenvptr = (char *)__crtGetEnvironmentStringsA(); //获取坏境变量信息的首地址
173
174 _setargv(); //传参到 _argc _argv 中
175 _setenvp(); //传参到 env 中
176 #endif /* WPRFLAG */
177
178 _cinit(); //用于全局数据和浮点寄存器的初始化 /* do C data initialize */
179
180 #ifdef _WINMAIN_
181
182 StartupInfo.dwFlags = 0;
183 GetStartupInfo( &StartupInfo );
184
185 #ifdef WPRFLAG
186 lpszCommandLine = _wwincmdln();
187 mainret = wWinMain(
188 #else /* WPRFLAG */
189 lpszCommandLine = _wincmdln();
190 mainret = WinMain(
191 #endif /* WPRFLAG */
192 GetModuleHandleA(NULL),
193 NULL,
194 lpszCommandLine,
195 StartupInfo.dwFlags & STARTF_USESHOWWINDOW
196 ? StartupInfo.wShowWindow
197 : SW_SHOWDEFAULT
198 );
199 #else /* _WINMAIN_ */
200
201 #ifdef WPRFLAG
202 __winitenv = _wenviron;
203 mainret = wmain(__argc, __wargv, _wenviron);
204 #else /* WPRFLAG */
205 __initenv = _environ;
206 mainret = main(__argc, __argv, _environ);
207 #endif /* WPRFLAG */
208
209 #endif /* _WINMAIN_ */
210 exit(mainret);
211 }
212 __except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
213 {
214 /*
215 * Should never reach here
216 */
217 _exit( GetExceptionCode() );
218
219 } /* end of try - except */
220
221 }
222
223
224
225 /***
226 *_amsg_exit(rterrnum) - Fast exit fatal errors
227 *
228 *Purpose:
229 * Exit the program with error code of 255 and appropriate error
230 * message.
231 *
232 *Entry:
233 * int rterrnum - error message number (amsg_exit only).
234 *
235 *Exit:
236 * Calls exit() (for integer divide-by-0) or _exit() indirectly
237 * through _aexit_rtn [amsg_exit].
238 * For multi-thread: calls _exit() function
239 *
240 *Exceptions:
241 *
242 *******************************************************************************/
243
244 void __cdecl _amsg_exit (
245 int rterrnum
246 )
247 {
248 #ifdef _WINMAIN_
249 if ( __error_mode == _OUT_TO_STDERR )
250 #else /* _WINMAIN_ */
251 if ( __error_mode != _OUT_TO_MSGBOX )
252 #endif /* _WINMAIN_ */
253 _FF_MSGBANNER(); /* write run-time error banner */
254
255 _NMSG_WRITE(rterrnum); /* write message */
256 _aexit_rtn(255); /* normally _exit(255) */
257 }
258
259 /***
260 *fast_error_exit(rterrnum) - Faster exit fatal errors
261 *
262 *Purpose:
263 * Exit the process with error code of 255 and appropriate error
264 * message.
265 *
266 *Entry:
267 * int rterrnum - error message number (amsg_exit only).
268 *
269 *Exit:
270 * Calls ExitProcess.
271 *
272 *Exceptions:
273 *
274 *******************************************************************************/
275
276 static void __cdecl fast_error_exit (
277 int rterrnum
278 )
279 {
280 #ifdef _WINMAIN_
281 if ( __error_mode == _OUT_TO_STDERR )
282 #else /* _WINMAIN_ */
283 if ( __error_mode != _OUT_TO_MSGBOX )
284 #endif /* _WINMAIN_ */
285 _FF_MSGBANNER(); /* write run-time error banner */
286
287 _NMSG_WRITE(rterrnum); /* write message */
288 ExitProcess(255); /* normally _exit(255) */
289 }
290
291 #ifndef WPRFLAG
292
293
294 #endif /* WPRFLAG */
295
296 #endif /* CRTDLL */
297
298 #else /* _WIN32 */
299
300 #include <cruntime.h>
301 #include <internal.h>
302 #include <stdlib.h>
303 #include <msdos.h>
304 #include <string.h>
305 #include <setjmp.h>
306 #include <dbgint.h>
307 #include <macos\types.h>
308 #include <macos\segload.h>
309 #include <macos\gestalte.h>
310 #include <macos\osutils.h>
311 #include <macos\traps.h>
312 #include <mpw.h>
313
314 static void __cdecl Inherit(void); /* local function */
315
316 int __cdecl main(int, char **, char **); //终于到了传说中 main 函数(用户入口) /*generated by compiler*/
317
318 unsigned long _GetShellStack(void);
319
320 static char * __cdecl _p2cstr_internal ( unsigned char * str );
321
322 extern MPWBLOCK * _pMPWBlock;
323 extern int __argc;
324 extern char **__argv;
325
326 /***
327 *__crt0()
328 *
329 *Purpose:
330 * This routine does the C runtime initialization, calls main(), and
331 * then exits. It never returns.
332 *
333 *Entry:
334 *
335 *Exit:
336 * This function never returns.
337 *
338 *******************************************************************************/
339
340 void __cdecl __crt0 (
341 )
342 {
343 int mainret;
344 char szPgmName[32];
345 char *pArg;
346 char *argv[2];
347
348 #ifndef _M_MPPC
349 void *pv;
350
351 /* This is the magic stuff that MPW tools do to get info from MPW*/
352
353 pv = (void *)*(int *)0x316;
354 if (pv != NULL && !((int)pv & 1) && *(int *)pv == 'MPGM') {
355 pv = (void *)*++(int *)pv;
356 if (pv != NULL && *(short *)pv == 'SH') {
357 _pMPWBlock = (MPWBLOCK *)pv;
358 }
359 }
360
361 #endif /* _M_MPPC */
362
363 _environ = NULL;
364 if (_pMPWBlock == NULL) {
365 __argc = 1;
366 memcpy(szPgmName, (char *)0x910, sizeof(szPgmName));
367 pArg = _p2cstr_internal(szPgmName);
368 argv[0] = pArg;
369 argv[1] = NULL;
370 __argv = argv;
371
372 #ifndef _M_MPPC
373 _shellStack = 0; /* force ExitToShell */
374 #endif /* _M_MPPC */
375 }
376 #ifndef _M_MPPC
377 else {
378 _shellStack = _GetShellStack(); //return current a6, or first a6
379 _shellStack += 4; //a6 + 4 is the stack pointer we want
380 __argc = _pMPWBlock->argc;
381 __argv = _pMPWBlock->argv;
382
383 Inherit(); /* Inherit file handles - env is set up by _envinit if needed */
384 }
385 #endif /* _M_MPPC */
386
387 /*
388 * call run time initializer
389 */
390 __cinit();
391
392 mainret = main(__argc, __argv, _environ);
393 exit(mainret);
394 }
395
396
397 #ifndef _M_MPPC
398 /***
399 *Inherit() - obtain and process info on inherited file handles.
400 *
401 *Purpose:
402 *
403 * Locates and interprets MPW std files. For files we just save the
404 * file handles. For the console we save the device table address so
405 * we can do console I/O. In the latter case, FDEV is set in the _osfile
406 * array.
407 *
408 *Entry:
409 * Address of MPW param table
410 *
411 *Exit:
412 * No return value.
413 *
414 *Exceptions:
415 *
416 *******************************************************************************/
417
418 static void __cdecl Inherit (
419 void
420 )
421 {
422 MPWFILE *pFile;
423 int i;
424 pFile = _pMPWBlock->pFile;
425 if (pFile == NULL) {
426 return;
427 }
428 for (i = 0; i < 3; i++) {
429 switch ((pFile->pDevice)->name) {
430 case 'ECON':
431 _osfile[i] |= FDEV | FOPEN;
432 _osfhnd[i] = (int)pFile;
433 break;
434
435 case 'FSYS':
436 _osfile[i] |= FOPEN;
437 _osfhnd[i] = (*(pFile->ppFInfo))->ioRefNum;
438 break;
439 }
440 pFile++;
441 }
442 }
443
444 #endif /* _M_MPPC */
445
446
447
448 static char * __cdecl _p2cstr_internal (
449 unsigned char * str
450 )
451 {
452 unsigned char *pchSrc;
453 unsigned char *pchDst;
454 int cch;
455
456 if ( str && *str ) {
457 pchDst = str;
458 pchSrc = str + 1;
459
460 for ( cch=*pchDst; cch; --cch ) {
461 *pchDst++ = *pchSrc++;
462 }
463
464 *pchDst = '\0';
465 }
466
467 return( str );
468 }
469
470 #endif /* _WIN32 */
471
printf:
printf 的三大功能:
①、 格式化。
②、 输出到标准输出设备。
③、 支持多文件。