25

我正在使用 ARM Cortex M3 芯片(STM32F2),ST 提供了一个“标准外设库”。它有一些有用的 .c 和 .h 文件。它也有 .s 文件。

这些 .s 文件在 C 项目上下文中的用途是什么?如何获取我的编译器/链接器/?考虑到他们?

4

4 回答 4

36

.s 扩展名是 GNU 和许多其他工具链用于汇编文件的约定。

最后我查看了 STM32 标准外设库本身不包含汇编文件,但是 CMSIS 库包含各种 STM32 部件的启动代码,例如 startup_stm32f2xx.s 是所有 STM32F2xx 系列设备的启动代码。不同的工具链有不同的实现;您需要构建和链接与您的特定零件和工具链关联的文件。如果您正在使用构建和运行的示例项目或为您创建特定于部件的项目的 IDE,那么这可能已经完成 - 如果您有运行它的代码肯定有。

您如何构建和链接代码将取决于您使用的工具链。大多数基于 IDE 的工具会自动识别扩展名并调用汇编程序来生成一个目标文件,该文件将像其他任何文件一样被链接。确切的内容在工具链版本之间略有不同,但主要是创建 C 运行时环境(堆栈和堆)、初始化处理器、定义初始中断/异常向量表、初始化静态数据并跳转到 main()。

例如,Keil/ARM RealView 版本的文件核心如下所示:

; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

Reset_Handler是处理器复位后将设置的地址程序计数器 (PC) 寄存器。

SystemInit是执行大部分初始化的外部 C 代码函数 - 这可能需要针对您的硬件进行定制。Cortex-M 的不寻常之处在于它可以在复位后立即开始运行 C 代码,因为向量表包括复位地址和初始堆栈指针地址,复位时会自动加载到 SP 寄存器。因此,您不需要太多的汇编知识即可运行。

__main()是编译器为您的 C 代码提供的入口点。它不是您编写的 main() 函数,而是在调用“main()”函数之前对标准库、静态数据、堆进行初始化。

GCC 版本涉及更多,因为它完成__main()了 Keil/ARM RealView 版本中完成的大部分工作,但本质上它执行相同的功能。

请注意,CMSISSystemInit()在 system_stm32f2xx.c 中定义,并且可能需要为您的电路板定制(正确的晶体频率、PLL 设置、外部 SRAM 配置等)。因为这是 C 代码,并且注释很好,所以您可能会更适应它。

于 2012-03-22T11:21:42.013 回答
8

它们通常包含汇编代码。汇编器将它们转换为目标文件,然后由链接器将其与主要内容链接。但我想它确实取决于编译器、工具链等。

于 2012-03-21T09:11:59.567 回答
2

.s 文件通常包含向量表。它定义了发生中断时系统应该做什么。该表(代码)放置在您在链接器文件中定义的内存地址中。例如,每次重置发生时,您的处理器应该从哪里开始,或者更确切地说应该从哪里开始,它应该运行什么代码。同样,还有其他处理程序(中断向量)。在 STM32 中,控制器通常在特定的处理程序上循环。如以下示例所示:有关详细说明,请参阅此链接

    .section INTERRUPT_VECTOR, "x"
    .global _Reset
    _Reset:
      B Reset_Handler /* Reset */
      B . /* Undefined */
      B . /* SWI */
      B . /* Prefetch Abort */
      B . /* Data Abort */
      B . /* reserved */
      B . /* IRQ */
      B . /* FIQ */

    Reset_Handler:
      LDR sp, =stack_top
      BL c_entry
      B .

此汇编代码稍后会转换为目标文件并与您的 .c 文件和 .ld 链接以创建 .elf 或 .bin 文件。

于 2019-03-13T10:20:27.603 回答
1

您可能已经为您的 ST 套件提供了基于 Keil 的开发环境。根据编译器的版本,项目文件应该有不同的 C、C++ 和汇编代码部分。在您的 IDE 中,打开您的项目并查找“项目属性”或类似的东西。

您可以在汇编代码中导入和导出符号,以便它与 C/C++ 代码链接。使用 Keil,这一切都可以很好地集成。

EXPORT 指令告诉汇编器公开指定的符号,以便您的 C/C++ 代码可以链接到它。

IMPORT 指令告诉汇编器指定的符号是在别处定义的,并将在链接时解析。

于 2012-03-22T00:08:21.570 回答