基于stm32f103的MDK汇编先容
一、ARM汇编语法简介
汇编语言是一种底层的语言,需要依赖硬件举行编写,根本换个硬件步伐就需要重新编写,实在在stm32的C语言在呆板执行时也要被转换为汇编语言再转换为呆板代码执行。汇编语言与其他高级语言差别的地方在于,对数据或寄存器的利用是通过各种指令完成的,主要有跳转指令、数据处置处罚指令、步伐状态寄存器(PSR)处置处罚指令、加载/存储指令、协处置处罚器指令、异常产生指令6大指令,常用指令集的先容与使用可参考以下文章:
ARM汇编指令集
ARM汇编指令集汇总
二、MDK创建汇编工程
1、汇编工程的创建与C语言工程的创建有所差别,我们这里新建一个汇编工程,完成对一个汇编文件的编写及调试,keil也可执行多文件的汇编编译调试,具体方法参考Keil 汇编asm/A51多个文件。
2、keil创建工程
(1)选择生存路径时尽量不要太深,名字不包罗中文,切记不要直接丢桌面,放在文件夹里。
(2)选择芯片类型
(3)配置运行情况(如果自己的步伐中写入了启动文件的内容则不需要添加startup)
(4)添加源文件
工程创建完成。
三、编译测试及输出表明
1、测试代码
代码实现将寄存器r5、r6、r7、r8的值设置为0x00000005``0x00000006``0x00000007``0x00000008
- 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
复制代码 2、编译Debug调试查察寄存器地点
(1)编译结果无误则工程配置正确
(2)调试查察
(3)先运行步伐,然后停止。
(4)在func01执行处设置断点
(5)运行代码后,r5的值没有改变。
(6)取消断点后,运行步伐,寄存器的值发生改变,且与步伐设定一样。
3、输出hex文件表明
(1)设置工程输出hex文件
(2)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
5.最后一个字节 0xf2为校验和。
校验和的算法为:盘算 0xf2前所有16进制码的累加和(不计进位),查验和 = 0x100 - 累加和
‘04’ ‘05’,都是用来提供地点信息的。每次遇到这2个记录的时候,都可以根据记录盘算出一个“基”地点。对于背面的数据记录,盘算地点的时候,都是以这些“基”地点为根本的。
HEX文件都是由记录(RECORD)组成的。在HEX文件内里,每一行代表一个记录。记录的根本格式为:
:020000040800F2
:1000000048B6002085010008B1450008252B0108ED
:10001000B9450008C1450008C945000800000000B6
:00000001FF
四、简朴的汇编点灯步伐
1、步伐中包罗了启动文件内容,新建工程不添加启动文件
2、测试代码
- LED0 EQU 0x42218194 ;LED0 (PB5)的bit-bond地点RCC_APB2ENR EQU 0x40021018GPIOB_CRL EQU 0x40010C00Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3Stack_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 ENTRYReset_Handler BL LED_InitMainLoop BL LED_ON BL Delay BL LED_OFF BL Delay B MainLoop LED_Init PUSH {R0,R1, LR} LDR R0,=RCC_APB2ENR ORR R0,R0,#0x08 ;使能GPIOB LDR R1,=RCC_APB2ENR STR R0,[R1] LDR R0,=GPIOB_CRL BIC R0,R0,#0XFF0FFFFF ;配置为模仿输入 LDR R1,=GPIOB_CRL STR R0,[R1] LDR R0,=GPIOB_CRL ORR R0,R0,#0X00300000 ;推挽输出 LDR R1,=GPIOB_CRL STR R0,[R1] MOV R0,#1 LDR R1,=LED0 STR R0,[R1] POP {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} END
复制代码 添加新的汇编文件,放入以上代码,编译下载。
3、代码简介
(1)预界说
每个需要用到的寄存器地点界说一个名字,类似于C语言的#define。bit-bond地点可查询尺度库的sys.h文件中的盘算方法,RCC和GPIO的地点是固定的,可从STM32的手册查询,大概根据ST官方的库文件查找盘算。
(2)分配栈空间
(3)分配向量表
(4)开始代码段
通知汇编器,开始代码段。
这段的意思是,汇编器支持THUMB指令,代码段按8字节对齐。
ENTRY下令:声明整个程式的入口点,入口点有且仅有一个。
(5)步伐运行
1、BL:带链接的跳转指令。当使用该指令跳转时,当前地点(PC)会自动送入LR寄存器。
2、B:无条件跳转。
3、PUSH和POP:可以看到,所有的子步伐都是由PUSH和POP包起来的。PUSH {R0,R1, LR}的意思即把R0,R1,LR中的值放入堆栈中。由于主程式中使用BL跳转指令,所以LR中的值实际上就是当前PC的值。而POP {R0,R1,PC}的意思便是将栈中之前存的R0,R1,LR的值返还给R0,R1,PC。这样就完成了子步伐的返回。
4、LDR和STR:寄存器的装载和存储指令。
LDR是把地点装载到寄存器中(好比R0)。
STR是把值存储到寄存器所指的地点中。
5、ORR和BIC:
ORR 按位或利用。ORR R0,R0,#0x04意思即将R0中的数或上0x04,再将结果送往R0中。实际意思就是将R0的第二位置1,其他位稳定。
BIC 先把立刻数取反,再按位与。
6、CMP和BCC:CMP是比力两个数,相等或大于则将标志位C置位,否则将C清零。BCC是个组合指令,实际为B+CC,意思是如果C=0则跳转。
CMP R2,#15; 盘算R2-15的值,若是R2=15,则C=1。
BCC DelayLoop0;若是C=0,则跳到DelayLoop0,若是c=1,则不跳转。
来源:https://blog.csdn.net/zmhDD/article/details/111915285
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |