我知道在C / C ++和Java中,程序的切入点是函数main()
,
现在我有以下两个问题,
用MASM,NASM和其他语言编写的程序入口点是什么?
CPU知道在哪里找到程序入口点的惯例是什么?
== - 编辑 - ==
问题2不是一个有意义的问题,因为CPU负责找到入口点是错误的。没有这样的惯例。请参阅Eric Lippert
的说明。
答案 0 :(得分:6)
在汇编中(MASM和NASM都只是汇编程序,即将汇编源代码转换为机器代码的程序),没有默认入口点。您通常使用汇编程序指令指定它。
引用的地址最后会出现在二进制(可执行文件)文件的标题中,这样操作系统就可以找出跳转的位置。
对于ELF二进制文件(在许多操作系统上使用),请参阅e_entry
标题字段:
e_entry
该成员提供系统首先转移控制的虚拟地址,从而启动该过程。如果文件没有关联的入口点,则此成员保持为零。
这也发生在C语言中,除了当然编译器位于源文件和可执行文件之间,因此它将所需的引用插入main()
(或者实际上,通常是在{{}之前运行的init例程{1}}。
Java不适用于原始二进制文件,它在JVM上的程序,所以它并没有真正比较。
答案 1 :(得分:2)
入口点通常不是由编译器定义的,而是由链接器定义的。例如,请参阅GCC的ld --entry
或VC ++的link /ENTRY:
。
在C和C ++中,默认入口点通常位于标准库(GCC IIRC中的_start
)中,该函数最终会调用用户main()
。
Java,拥有JVM,程序入口点在JVM中进行了硬编码。
如果你在汇编中编程,它取决于你是否使用某种语言的标准库:
main()
功能,所有功能都与C一样。_start
)命名您的入口点。例如,在编译和链接空C文件时,比较这两个命令的错误消息:
$ gcc empty.c
/usr/lib/gcc/i686-linux-gnu/4.8/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: error: ld returned 1 exit status
$ gcc -nostdlib empty.c
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 00000000080480b8
您可以使用以下内容更改条目名称:
$ gcc -nostdlib -Wl,-entry,begin empty.c
/usr/bin/ld: warning: cannot find entry symbol begin; defaulting to 00000000080480b8
答案 2 :(得分:2)
CPU知道在哪里找到程序入口点的惯例是什么?
这个问题无法回答,因为它预示着虚假。 CPU 没有这样的约定,因为它不是分析和运行可执行文件的 CPU 。这是操作系统的功能。它是如何做的取决于可执行文件的格式。例如,在使用MZ文件格式的16位MSDOS程序中,文件的第15和第16字节包含指令指针的起始值。 MSDOS可以在指示CPU应该执行哪些代码时使用此信息。