简单的STM32汇编程序

  • Post author:
  • Post category:其他




一、简单的汇编程序


1.创建一个工程


1.打开Kiel,project->new μvison Project;

2.然后选择自己保存文件的路径;

3.之后选择自己的芯片、环境、启动文件,如下图;

在这里插入图片描述

在这里插入图片描述

这里我选择的芯片是STM32F03RC。



二、添加文件


1.鼠标右键单击Source Group 1,选择Add New Item to Group



2.选择 Asm File (.s) ,设置源文件的名称(此处源文件命名为TEST),点击Add


在这里插入图片描述


3.之后写入代码

 AREA MYDATA, DATA
	
 AREA MYCODE, CODE
	ENTRY
	EXPORT __main

__main
	MOV R0, #10
	MOV R1, #11
	MOV R2, #12
	MOV R3, #13
	;LDR R0, =func01

	BL	func01
	;LDR R1, =func02
	BL	func02
	
	BL 	func03
	LDR LR, =func01
	LDR PC, =func03
	B .
		
func01
	MOV R5, #05
	BX LR
	
func02
	MOV R6, #06
	BX LR
	
func03
	MOV R7, #07
	MOV R8, #08	
	BX LR


4.之后根据自己的实际情况进行选择自己的仿真器及模式


在这里插入图片描述

此处是编译后的信息。



四、结果分析

在这里插入图片描述

此处为编译后的hex文件。

第一行内容含义


0x02


该行数据中有两个数据


0x00 0x00


本行数据的起始地址位


0x04


用来标识扩展线性地址的记录

该字节还可以是其他值,下面是其他值的含义


00

:用来记录数据,HEX文件的大部分记录都是数据记录


01

:用来标识文件结束,放在文件的最后,标识HEX文件的结尾


02

:用来标识扩展段地址的记录


03

:开始段地址记录


05

:开始线性地址记录


0x08 0x00


该行两个字节的数据

数据类型是 04 ,即该行记录的是一个拓展地址(0x08 0x00 是地址信息,用法是将该地址(0x0800<<16) 后作为基地址


0xF2


校验和,校验和= 0x100 – 累加和



五、用汇编程序完成 每间隔1秒钟闪烁一次LED的程序

创建一个新工程,步骤跟上面步骤基本一致,但不需要添加启动代码(startup,core)。

写入代码:

LED0 EQU 0x40011004;定义引脚PC2 
RCC_APB2ENR EQU 0x40021018;配置RCC寄存器,时钟
GPIOC_CRL EQU 0x40011000;配置CRL寄存器
Stack_Size      EQU     0x00000400;栈的大小
;分配一个STACK段,该段不初始化,可读写,按8字节对齐。分配一个大小为Stack_Size的存储空间,并使栈顶的地址为__initial_sp。
                AREA    STACK, NOINIT, READWRITE, ALIGN=3;NOINIT: = NO Init,不初始化。READWRITE : 可读,可写。ALIGN =3 : 2^3 对齐,即8字节对齐。
Stack_Mem       SPACE   Stack_Size
__initial_sp

                AREA    RESET, DATA, READONLY

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                    
                    
                AREA    |.text|, CODE, READONLY;开始代码段
                    
                THUMB
                REQUIRE8
                PRESERVE8
                    
                ENTRY
Reset_Handler 
                BL LED_Init;BL:带链接的跳转指令。当使用该指令跳转时,当前地址(PC)会自动送入LR寄存器
MainLoop        BL LED_ON
                BL Delay
                BL LED_OFF
                BL Delay
                
                B MainLoop;B:无条件跳转。
             
LED_Init;LED初始化
                PUSH {R0,R1, LR};R0,R1,LR中的值放入堆栈
                
                LDR R0,=RCC_APB2ENR;LDR是把地址装载到寄存器中(比如R0)。
                ORR R0,R0,#0x04;ORR 按位或操作,将将R0的第二位置1,其他位不变
                LDR R1,=RCC_APB2ENR
                STR R0,[R1];STR是把值存储到寄存器所指的地址中。
                
                LDR R0,=GPIOC_CRL
                BIC R0,R0,#0x0F;BIC 先把立即数取反,再按位与
                LDR R1,=GPIOC_CRL
                STR R0,[R1]
                
                LDR R0,=GPIOC_CRL
                ORR R0,R0,#0x03
                LDR R1,=GPIOC_CRL
                STR R0,[R1]
                ;将PC2置1
                MOV R0,#1 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC};将栈中之前存的R0,R1,LR的值返还给R0,R1,PC

             
LED_ON
                PUSH {R0,R1, LR}    
                
                MOV R0,#0
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC}
             
LED_OFF
                PUSH {R0,R1, LR}    
                
                MOV R0,#1 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC}             
             
Delay
                PUSH {R0,R1, LR}
                
                MOVS R0,#0
                MOVS R1,#0
                MOVS R2,#0
                
DelayLoop0        
                ADDS R0,R0,#1

                CMP R0,#330
                BCC DelayLoop0
                
                MOVS R0,#0
                ADDS R1,R1,#1
                CMP R1,#330
                BCC DelayLoop0

                MOVS R0,#0
                MOVS R1,#0
                ADDS R2,R2,#1
                CMP R2,#15
                BCC DelayLoop0
                
                
                POP {R0,R1,PC}    
             
    ;         NOP
             END


AREA命令

:AREA 命令指示汇编器汇编一个新的代码段或数据段。段是独立的、指定的、不可见的代码或数据块,它们由链接器处理;


SPACE命令

:SPACE 命令保留一个用零填充的存储器块;


ENTRY命令

:声明整个程式的入口点,入口点有且仅有一个;



六、总结

在有别人的成果下,也能做出来结果,但自己独自完全不会,缺少兴趣,也缺少耐心,总之,还得加油。



版权声明:本文为weixin_48547489原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。