ST意法半导体
直播中

李浯

7年用户 1050经验值
私信 关注
[问答]

请问如何在stm32cubeide中运行汇编代码?

我在 Uvision5 上创建了一个小汇编项目,但我很快就达到了代码大小限制,我无法管理我的汇编代码在 STM32cubeide 上运行,请问你知道如何运行汇编代码吗?







回帖(1)

罗宗保

2022-12-8 15:49:08
是的,你可以用STM32CubeIDE编写汇编代码并编译成功。然而,很少有人这样做,因为与 C 编程相比,编写程序所需的工作要复杂得多,最重要的是,它非常耗时。
原则上,您可以将汇编程序插入到任何 CubeIDE 项目中,无论是现有项目还是新项目。但是,应该注意 GNU 汇编器的语法在某些方面可能与其他汇编器的不同。
基本上,您可以通过在 STM32CubeIDE 中创建来添加汇编代码:


  • 创建头文件,例如assembler.h



  • /*
  • * assembler.h
  • *
  • */

  • #ifndef APPLICATION_USER_CORE_ASSEMBLER_H_
  • #define APPLICATION_USER_CORE_ASSEMBLER_H_

  • extern void ASM_SystemInit(void);
  • extern void ASM_Function(void);

  • #endif /* APPLICATION_USER_CORE_ASSEMBLER_H_ */




  • 将它添加到main.c



  • /* USER CODE BEGIN Includes */
  • #include "assembler.h"
  • /* USER CODE END Includes */




  • 在源代码块中创建文件assembler.s

assembler.s 的内容可能如下所示(这个小示例还包含一个初始化,因为它是一个纯 ASM 项目):


  • /*
  • * assembler.s
  • *
  • */

  •   .syntax unified

  •   .text
  •   .global ASM_SystemInit
  •   .global ASM_Function
  •   .thumb_func

  •   .equ  RCC_BASE_ADDR,  0x40021000
  •   .equ  o_RCC_CR,       0x00       // offset to RCC_CR
  •   .equ  o_RCC_CFGR,     0x08       // offset to RCC_CFGR
  •   .equ  o_RCC_PLLCFGR,  0x0C       // offset to RCC_PLLCFGR
  •   .equ  o_RCC_AHB2ENR,  0x4C       // offset to RCC_AHB2ENR

  •   .equ  GPIOA_BASE_ADDR,0x48000000
  •   .equ  o_GPIOA_MODER,  0x00       // offset to GPIOA_MODER
  •   .equ  o_GPIOA_OTYPER, 0x04       // offset for GPIOA Output PP/OD
  •   .equ  o_GPIOA_OSPEEDR,0x08       // offset for GPIOA Output Speed
  •   .equ  o_GPIOA_PUPDR,  0x0C       // offset for GPIOA PU/PD

  •   .equ  GPIOA_BSRR,     0x48000018 // GPIOA Bit set reset register

  •   .equ  COUNTER,        10000
  • //------------------------------------------------------------------------------------------------
  •   ASM_SystemInit:

  •   // Clock configuration, 16 MHz HSI as PLL clock source
  •   LDR R1, =RCC_BASE_ADDR           // Load RCC configuration register address in R1

  •   LDR R0, =0x06000802              // PLLPDIV=0, PLLR=8, PLLQ=2, PLLP=7, PLLN=16, PLLM=1, HSI16->PLL
  •   STR R0, [R1, o_RCC_PLLCFGR]      // store into RCC_PLLCFGR

  •   ORR R0, #0x01000000              // set PLLREN (bit 24)
  •   STR R0, [R1, o_RCC_PLLCFGR]      // store into RCC_PLLCFGR

  •   LDR R0, [R1, o_RCC_CR]           // read RCC_CR
  •   ORR R0, #0x01000000              // set PLLON (bit 24)
  •   STR R0, [R1, o_RCC_CR]           // store into RCC_CR

  •   ASM_SystemInit_1:
  •   LDR R0, [R1, o_RCC_CR]           // read RCC_CR
  •   LSLS R0, #6                      // Logical Shift Left by 6
  •   BPL.N ASM_SystemInit_1           // Branch if N flag = 0 (= positive or zero, see PM0214, table 24)

  •   [...]

  •   BX LR                            // Return from function

  • //------------------------------------------------------------------------------------------------
  •   ASM_Function:

  •   turnON:
  •   // Set output high
  •   LDR R1, =GPIOA_BSRR
  •   LDR R0, =0x00000020
  •   STR R0, [R1]

  •   LDR R2, =COUNTER
  •   delay1:
  •   SUBS R2, R2, #1                  // R2 = R2 - 1, R2 = 0?
  •   BNE delay1                       // stay in loop delay1 if not equal to zero

  •   turnOFF:
  •   // Set output low
  •   LDR R0, =0x00200000
  •   STR R0, [R1]

  •   LDR R2, =#COUNTER
  •   LSL R2, #6                       // Logical Shift Left

  •   delay2:
  •   SUBS R2, R2, #1                  // R2 = R2 - 1, R2 = 0?
  •   BNE delay2                       // stay in loop delay1 if not equal to zero

  •   delayDone:
  •   B turnON                         // Jump to turnON




  • 最后使用以下语句在 main.c 中启动此汇编程序例程,而第一个是在第二个未退出时返回的函数(无限循环):



  • int main(void)
  • {
  •   /* USER CODE BEGIN 1 */
  •   ASM_SystemInit();
  •   ASM_Function();
  •   /* USER CODE END 1 */
  • }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分