您的第一个问题已在指南中得到解答。
当您在操作系统上加载程序时,您的.data节(基本上非零全局变量)会从“binary”加载到内存中的右侧偏移量中,以便当程序启动那些内存位置代表你的变量有这些值。
unsigned int x=5;
unsigned int y;
作为一名C程序员,您编写了上面的代码,并且您希望x在您第一次使用时是5?那么,如果从闪存引导,裸机,你没有一个操作系统将这个值复制到你的RAM,有人必须这样做。进一步的所有.data的东西都必须在闪存中,数字5必须在闪存的某个地方,以便它可以复制到RAM。所以你需要一个flash地址和一个ram地址。两个地址为同一件事。
这就开始回答你的第二个问题,对于你编写的每一行C代码,你都假设任何函数都可以调用任何其他函数。你想能够调用函数是吗?而且你希望能够有局部变量,并且你希望上面的变量x为5,并且你可以假设y将为零,但是,幸好编译器开始警告这个问题。通用C的最小启动代码设置了堆栈指针,它允许你调用其他函数,并且有局部变量,并且函数的长度超过一行或两行代码,它将清零.bss,以便上面的y变量是零,它将值5复制到ram中,以便在运行入口点C函数的代码时x已准备就绪。
如果你没有操作系统,那么你必须有代码来做到这一点,是的,有许多许多沙箱和工具链设置为已经有启动和链接脚本的各种平台,以便你可以只是
gcc -O myprog.elf myprog.c
现在,这并不意味着你可以使系统调用没有... ...系统的printf,FOPEN,等等。但是,如果你下载这些工具链的一个它意味着你不确实有写链接器脚本或引导程序。
但它仍然是有价值的信息,请注意启动代码和链接器脚本也是基于操作系统的程序所必需的,它只是针对您的操作系统的本机编译器假定您将主要为该操作系统编写程序,结果他们在该工具链中提供了链接器脚本和启动代码。