转自 http://hi.baidu.com/liu_bin0101/blog/item/03e3a9ec4e0fd5d72e2e21b9.html
程序入口与编译器没有什么关系, 关键是链接链接器(UNIX的用的ld和WINDOWS下用的LINK.EXE)
ld 用参数-e entry参数指定程序入口为entry
LINK.EXE 用/ENTRY:symbol指定程序入口为symbol
通常, ld/LINK.EXE 不是被直接运行的, 而是由编译器用适当的参数去调用的.
C/C++编译器的完成编译之后会用适当的参数去调用ld/LINK.EXE告诉链接器程序的入口.
WINDOWS下VC编译的程序程序入口点是WinMainCRTStartup(/SUBSYSTEM:WINDOWS, WIN32 GUI 程序)或mainCRTStartup(/SUBSYSTEM:CONSOLE 即WIN32控制台程序).
UNIX下cc/gcc设置的缺省程序入口是_start.
不论是WinMainCRTStartup, mainCRTStartup还是_start, 在链接器生成可执行程序之后, 入口点信息都保存在可执行文件中了.
WinMainCRTStartup, mainCRTStartup或_start函数都是由C标准库实现的, 这些里面通常做一些初始化工作, 包括一些需要用汇编语言才能完成的工作, 然后调用的main函数(WIN32 GUI 程序是WinMain).
这个过程可以用一个例子来说明, 下面是FreeBSD 6.2 的libc的crt1.c, 里面有_start函数的实现:
C/C++ code
-
/*
LINTLIBRARY
*/
/*
-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef lint
#ifndef __GNUC__
#error
"GCC is needed to compile this file"
#endif
#endif
/* lint */
#include
<
stdlib.h
>
#include
"
libc_private.h
"
#include
"
crtbrand.c
"
extern
int
_DYNAMIC;
#pragma
weak _DYNAMIC
typedef
void
(
*
fptr)(
void
);
extern
void
_fini(
void
);
extern
void
_init(
void
);
extern
int
main(
int
,
char
**
,
char
**
);
extern
void
_start(
char
*
, ...);
#ifdef GCRT
extern
void
_mcleanup(
void
);
extern
void
monstartup(
void
*
,
void
*
);
extern
int
eprol;
extern
int
etext;
#endif
char
**
environ;
const
char
*
__progname
=
""
;
static
__inline fptr
get_rtld_cleanup(
void
)
{
fptr retval;
#ifdef __GNUC__
__asm__(
"
movl %%edx,%0
"
:
"
=rm
"
(retval));
#else
retval
=
(fptr)
0
;
/*
XXXX Fix this for other compilers
*/
#endif
return
(retval);
}
/*
The entry function.
*/
void
_start(
char
*
ap, ...)
{
fptr cleanup;
int
argc;
char
**
argv;
char
**
env;
const
char
*
s;
#ifdef __GNUC__
__asm__(
"
and $0xfffffff0,%esp
"
);
#endif
cleanup
=
get_rtld_cleanup();
argv
=
&
ap;
argc
=
*
(
long
*
)(
void
*
)(argv
-
1
);
env
=
argv
+
argc
+
1
;
environ
=
env;
if
(argc
>
0
&&
argv[
0
]
!=
NULL) {
__progname
=
argv[
0
];
for
(s
=
__progname;
*
s
!=
'
\0
'
; s
++
)
if
(
*
s
==
'
/
'
)
__progname
=
s
+
1
;
}
if
(
&
_DYNAMIC
!=
NULL)
atexit(cleanup);
else
_init_tls();
#ifdef GCRT
atexit(_mcleanup);
#endif
atexit(_fini);
#ifdef GCRT
monstartup(
&
eprol,
&
etext);
#endif
_init();
exit( main(argc, argv, env) );
}
#ifdef GCRT
__asm__(
"
.text
"
);
__asm__(
"
eprol:
"
);
__asm__(
"
.previous
"
);
#endif
__asm__(
"
.ident\t\"$FreeBSD: src/lib/csu/i386-elf/crt1.c,v 1.14 2005/05/19 07:36:07 dfr Exp $\"
"
);
至于楼主想知道的"如何让没有main函数的C程序变成可执行文件?"
涉及到自己链接给链接程序传参数, 有一个例子可以试试.
C/C++ code
-
/*
-
* name: entry_start.c
* auth: mymtom
* date: 2008-02-18
*/
#include
<
unistd.h
>
#include
<
string
.h
>
void
_start(
void
)
{
(
void
)write(
1
, __func__, strlen(__func__));
(
void
)write(
1
,
"
\n
"
,
1
);
_exit(
0
);
}
这个程序在FreeBSD 6.2 和Fedora Core 6上可以用下面的命令编译, 也可以运行.
gcc -c entry_start.c
ld -o entry_start -static -e _start entry_start.o -lc
但是在运行Loongson Debian Linux V4.0的龙芯福珑迷你(龙芯2E处理器)的机器上会core dump,
原因应该是没有初始化C运行环境而调用了C库函数引起的. 毕竟这不是写C程序的正规方法
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)