• 05 如何写Keil ARM M3汇编函数和汇编宏定义函数


    作者将狼才鲸
    创建日期2022-11-05

    Gitee工程和源码地址:才鲸嵌入式 / ARM-Cortex-M3从汇编到C_从Boot到应用教程
    CSDN文章阅读地址:ARM Cortex-M3从汇编到C,从Boot到应用的教程
    Bilibili视频讲解地址(待完成):才鲸嵌入式


    工程名称作用
    01_Hello_world使用Keil的模拟器在虚拟终端输出Hello world
    02_Keil_boot_commentsKeil自带汇编boot的注释
    03_Self_assembler_boot自行实现汇编boot
    04_Uart_loopback串口收发回环,使用Keil的虚拟终端窗口
    05_Assembler_func汇编函数的编写
    06_Hardware_arch_code将硬件相关的代码与系统逻辑代码分离
    07_OS_kernel移植操作系统线程管理模块
    08_OS_memory移植操作系统内存管理模块,实现malloc、free
    09_OS_filesystem移植操作系统文件系统模块

    5)05_Assembler_func

    • 如何写汇编函数,汇编宏定义函数

    • 工程和源码在本文档同级目录\src\05_Assembler_func\下

    • func.inc:

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; @brief	演示ARM M3的汇编宏定义函数
    ; @author	将狼才鲸
    ; @date		2022-11-10
    ; @note		File format: UTF-8
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;;;;;;;; 私有宏定义函数,本模块内部使用 ;;;;;;;;
    ;;
    ; \brief		将通用寄存器里事先存好的值写到地址中去
    ; \param[in]	$reg, 只能是一个通用寄存器如R0等,里面存放要写的值
    ; \param[in]	$addr, 立即数地址
    ;;
    				MACRO	; 宏定义函数
    				ADDR_W_REG $reg, $addr
    				; 将地址存在R1中
    				MOVW R1, #($addr & 0xffff)	; movw命令代表将值放在寄存器的低16位,清零高16位
    				MOVT R1, #($addr >> 16)		; movt命令代表将值放在寄存器的高16位,不影响低16位
    				STR $reg, [R1, #0x00]		; 将前面寄存器里的值放到后面R1+0的地址中,
    				MEND	; 宏定义函数结束
    
    ;;
    ; \brief		将地址里的值读到寄存器中
    ; \param[in]	$reg, 目的寄存器
    ; \param[in]	$addr, 要读的地址
    ;;
    				MACRO
    				ADDR_R_REG $reg, $addr
    				MOVW R1, #($addr & 0xffff)
    				MOVT R1, #(&addr >> 16)
    				LDR $reg, [R1, #0x00]	; *reg = *(R1 + 0)
    				MEND
    
    ;;;;;;;; 接口宏定义函数 ;;;;;;;;
    ;;
    ; \brief	将一个立即数写入到地址中
    ; \param[in]	$v, 要写入的值
    ; \param[in]	$addr, 要写的地址
    ;;
    				MACRO
    				ADDR_WRITE	$v, $addr
    				MOVW R0, #($v & 0xffff) ; 将要写入的值低16位转到寄存器
    				MOVT R0, #($v >> 16)	; 转存高16位
    				ADDR_W_REG R0, $addr	; 调用函数将R0写入到addr
    				MEND
    
    ;;
    ; \brief	读一个地址的数据,值放到R0中
    ; \param[in]	$addr, 要读的地址
    ; \param[out]	R0, 返回的值
    ;;
    				MACRO
    				ADDR_READ $addr
    				ADDR_R_REG R0, $addr	; 调用函数将addr中的值读到R0中
    				MEND
    
    				END
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • func.asm:
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; @brief	演示ARM M3汇编函数的编写,压栈弹栈,汇编宏定义函数等
    ; @author	将狼才鲸
    ; @date		2022-11-10
    ; @note		File format: UTF-8
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    				INCLUDE	func.inc	; 包含头文件,头文件没有规避递归包含,注意不要多次包含同一个文件
    
    				PRESERVE8
    				THUMB
    
    				AREA	|.text|, CODE, READONLY
    
    ;;
    ; \brief	汇编写的系统、硬件初始化函数,在main函数执行前先把DDR、PLL等准备好
    ;;
    __hw_init		PROC
    				EXPORT	__hw_init
    				PUSH	{R0, R1, R2, R3, LR}	; 先压栈
    				BL		__hw_device_init		; 调用没有参数的函数
    				POP		{R0, R1, R2, R3, LR}	; 最后再弹栈,不需要像51那样和压栈时顺序相反
    				BX		LR	; 返回调用的函数
    				ALIGN		; 取消字节对齐
    				ENDP		; 函数结束
    
    __hw_device_init	PROC
    				EXPORT	__hw_device_init
    				PUSH	{R0, R1, R2, R3, LR}
    				ADDR_WRITE 0x00, 0x40004100
    				;TODO 配置必要的寄存器
    				POP		{R0, R1, R2, R3, LR}
    				BX		LR
    				ALIGN
    				ENDP
    	
    				END
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
  • 相关阅读:
    开源模型应用落地-工具使用篇-向量数据库(三)
    聚乙二醇修饰单分散/功能化聚乙烯胺/热敏性PNVIBA/温敏性PNIPAAm接枝聚苯乙烯微球
    【玩转CSS】学成在线(文末素材源码自取)
    ECC(SM2) 简介及 C# 和 js 实现【加密知多少系列】
    3D激光SLAM:ALOAM---后端lasermapping 里程计到地图位姿更新维护
    电子体温计为什么会说不如水银准,分析了一下,这个锅它不背!!!
    顺序读写函数的介绍:fscanf & fprintf
    RationalDMIS2022校验测头
    SpringCloud01:Eureka的使用
    laravel练习03
  • 原文地址:https://blog.csdn.net/qq582880551/article/details/127795817