c程序中真正的入口也就是代码的起始并不是
main
函数
Linux
操作系统中有这样一条命令ld
也就是链接器- 链接器最后将各种各样的目录文件链接成可执行文件的时候它会去用到一个链接的脚本文件,可通过
ld --verbose
命令加参数就可以打印默认的链接脚本,查看脚本最上方的有一句话,它定义了代码和数据的起始地址 - 上图中的意思是可执行的代码数据段起始地址是
0x400000
,如果我们修改了脚本文件的起始地址,那么数据段和代码段都会相应的发生改变 - 可以通过打印出一个变量
_start
(符号)的地址进行查看
#include <stdio.h>
extern _start; /* 来自于外部的声明 */
int main(void)
{
printf("_start = %p\n", _start);
return 0;
}
- 也可以通过
objdump -d Executable File
进行反汇编查看真正代码的入口地址 - 可以看见上图反汇编中的一个起始,看机器代码
31 ed 49 89 d1 ...
,为了验证_start
符号进一步的说明是代码的起始,可通过objcopy -O
提取代码段并通过hexdump -C
进行查看
$ # objcopy -O binary[格式] -j .text[代码]/.data[数据] print[可执行文件] text.bin/data.bin[指令]
$ objcopy -O binary -j .text print text.bin
$ hexdump -C text.bin
- .