C 启动代码只写汇编混乱

Eng*_*999 3 c embedded assembly startup

据我了解,C 启动代码用于初始化 C 运行时环境、初始化静态变量、设置堆栈指针等,最后分支到 main()。

他们说这只能用汇编语言编写,因为它是特定于平台的。但是,这仍然不能用 C 编写并针对特定平台进行编译吗?

函数调用当然是不可能的,因为我们“很有可能”在那个阶段没有设置堆栈指针。我仍然看不到其他主要原因。提前致谢。

P__*_*J__ 6

只有在以下情况下才能用 C 语言编写启动代码:

  1. 实现提供了所有必要的内在函数来设置无法使用标准 C 设置的硬件功能
  2. 提供将代码和数据片段放置在特定位置和特定顺序的机制(例如 gcc 对 ld 链接器脚本的支持)。

如果两个条件都满足,就可以用C语言编写启动代码。

我使用自己的 C 语言编写的启动代码(而不是芯片供应商提供的代码)用于 Cortex-M 微控制器,因为 ARM 提供了 CMSIS 头文件以及所有需要的内联汇编函数,而基于 gcc 的工具链为我提供了完整的内存布局控制。


zwo*_*wol 6

事实上,用 C 编写早期启动代码的大部分问题是缺乏结构合理的堆栈。这比不能进行函数调用更糟糕。所有的C编译器的生成的机器代码假定一个堆栈,由ABI-指定寄存器所指向的,可被用于暂存存储的存在随时。改变这个假设将是大量的工作,以至于相当于编译器的一个完整的第二个“后端”——比继续在汇编中手动编写早期启动代码的工作量要多得多。

早期的引导代码,从开机启动机器,还必须做一堆通常不能从 C 访问的特殊操作,比如配置中断和虚拟内存。并且可能要处理代码没有加载到链接地址,或者重定位表没有处理,或者其他类似的问题;这些也打破了 C 编译器所做的普遍假设(例如,它可以随时注入调用memcpy)。

尽管如此,大多数用户模式 ​​C 库的启动代码实际上都是用 C 编写的,这正是您所想的原因。没有人愿意为每个受支持的 ISA 一遍又一遍地编写比绝对必要更多的汇编代码。