摘要:在学习STM32的路上开始是学的C语言尚未进行对汇编进行学习,因此抽出时间来学习一下在keil下的汇编语言。
一、 汇编语言简介
汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。
许多汇编程序为程序开发、汇编控制、辅助调试提供了额外的支持机制。有的汇编语言编程工具经常会提供宏,它们也被称为宏汇编器
汇编语言不像其他大多数的程序设计语言一样被广泛用于程序设计。在今天的实际应用中,它通常被应用在底层,硬件操作和高要求的程序优化的场合。驱动程序、嵌入式操作系统和实时运行程序都需要汇编语言。
具体学习参考请该博客什么是汇编语言
有兴趣的同学可以阅读下这篇汇编语言笔记(全)
二、 初步分析
- 新建完成
-
仿真器我的是ST-Link和小麦大叔的配置不同,但影响不大。
-
由于博主没有对汇编语言进行注释,所以我进行了一定的注释
AREA MYDATA, DATA ;AREA 功能:指示汇编器 汇编一段新的代码或数据区。在汇编时,必须至少有一个ARME指示符。DATA 包含数据,但不包含指令
AREA MYCODE, CODE;定义此标号是程序内的数据区
ENTRY;执行汇编程序的入口点,至少一个源文件中只能有一个
EXPORT __main//EXPORT ;明全局变量 _main 这个相当于函数入口
__main
MOV R0, #10 传送指令——MOV DST,SRC 指令的基本功能:(DST)<-(SRC) 将原操作数(字节或字)传送到目的地址。即将10写入RO
MOV R1, #11
MOV R2, #12
MOV R3, #13
;LDR R0, =func01;将func01的数据读入到R0中
BL func01 ;跳转指令但跳转之前,会在寄存器R14 中保存PC 的当前内容
;LDR R1, =func02;将func02的数据读入到R1中
BL func02
BL func03
LDR LR, =func01
LDR PC, =func03
B . ;死循环
func01
MOV R5, #05
BX LR ;跳转到LR寄存器里的地址执行
func02
MOV R6, #06
BX LR ;指令跳转到指令中所指定的目标地址
func03
MOV R7, #07
MOV R8, #08
BX LR ;跳转到LR寄存器里的地址执行
- 分析
由实验结果分析,分别对寄存器进行了赋值练习且结果与之前分析一致。
- 分析HEX文件
首行
0x02
0x00
0x00
0x04
0x08
0x00
0xF2
第一个字节0x02
表示本行数据长度;
第二、三字节0x00
0x00
表示本行数据的起始地址;
第四字节 0x04表示数据类型,数据类型有:0x00
、0x01
、0x02
、0x03
、0x04
、0x05
。
‘00’ Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录
‘01’ End of File Record: 用来标识文件结束,放在文件的最后,标识HEX文件的结尾
‘02’ Extended Segment Address Record: 用来标识扩展段地址的记录
‘03’ Start Segment Address Record:开始段地址记录
‘04’ Extended Linear Address Record: 用来标识扩展线性地址的记录
‘05’ Start Linear Address Record:开始线性地址记录
然后是数据,0x08
0x00
最后一个字节0xf2
为校验和。
三、 实验分析
3.1 实验要求
用汇编程序完成 每间隔1秒钟闪烁一次LED的程序
3.2 新建工程
成功新建
添加LED.s
文件
新建工程完成。
3.3 软件代码
LED0 EQU 0x422201b4
RCC_APB2ENR EQU 0x40021018
GPIOC_CRH EQU 0x40011004 ;预定义
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
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指令,代码段按8字节对齐
THUMB
REQUIRE8
PRESERVE8
ENTRY ;声明整个程序的入口
Reset_Handler
BL LED_Init
MainLoop BL LED_ON
BL Delay
BL LED_OFF
BL Delay
B MainLoop
LED_Init
PUSH {R0,R1, LR} ;将R0,R1,LR入栈
LDR R0,=RCC_APB2ENR
ORR R0,R0,#0x04
LDR R1,=RCC_APB2ENR
STR R0,[R1]
LDR R0,=GPIOC_CRH
BIC R0,R0,#0XFF0FFFFF ;配置为模拟输入模式
LDR R1,=GPIOC_CRH
STR R0,[R1]
LDR R0,=GPIOC_CRH
ORR R0,R0,#0X00300000 ;配置为通用推挽输出模式,最大速度为50MHz
LDR R1,=GPIOC_CRH
STR R0,[R1]
MOV R0,#1 ;将立即数1送入R0.
LDR R1,=LED0 ;将PC13 bit-bond的地址送入R1.
STR R0,[R1] ;将R0的值,也就是1,送给R1中的值所指向的地址中
POP {R0,R1,PC} ;将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 ;加法,R0=R0+1
CMP R0,#330 ;计算R0-330的值,R0<330,则C=0;否则C=1。
BCC DelayLoop0 ;若是C=0,则跳到DelayLoop0,若是c=1,则不跳转
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
3.4 编译烧录
通过该博客成功解决More than one section matches selector - cannot all be FIRST/LAST的解决方法(包含只有一个启动文件的解决方法)
3.5 实验结果
四、 总结
通过此次实验,我基本了解了汇编语言的一些指令以及作用。通过上手实践编写汇编语言的点灯程序,掌握了一些基本的汇编程序编译知识。中途遇到了很多问题,特别感谢我的老师和同学的帮助。