基于 MDK 创建汇编语言的STM32工程并分析HEX文件

文章内容
参搭建并配置Keil嵌入式开发环境,完成一个基于STM32汇编程序的编写。
1)记录build生成的 hex文件各段的大小,了解Hex文件格式及其前8个字节内容含义;
2)学习在没有硬件条件下进行仿真调试的方法,观察ARM寄存器变化状况。

实验环境:Keil 5
Keil 5百度网盘下载链接:https://pan.baidu.com/s/1BJ0jyr2Wf41_YyRZkLujgg
提取码:luha

1 基于 MDK 创建汇编语言的STM32工程

1.1 创建新工程

(1) 先点击 菜单栏的Project ,接着点击New uVision Project 创建新工程
在这里插入图片描述

(2)在弹出的窗口选择工程路径,输入工程名(可随意命名,最好全英文,这里命名为NEWTEST),并保存
在这里插入图片描述
(3)在新窗口中选择STM32F103VE 芯片(这里也可以选择其他合适的芯片)
在这里插入图片描述
(4)在新的窗口中:
CMSIS下选择CORE
DeviceStartup,其中包含了启动文件;
之后点击OK即可。
在这里插入图片描述

1.2 添加源文件

(1)鼠标右击Source Group 1
在这里插入图片描述
(2)点击Add New Item to Group 'Source Group 1'...
在这里插入图片描述
(3)在新窗口中:
点击 Asm File (.s) 添加汇编文件,然后设置文件名称(可随意命名,最好全英文,这里命名为Test),并点击 Add保存
在这里插入图片描述
添加完成后,可以看到如下界面:
在这里插入图片描述

1.3 编写汇编程序

Test.s框中输入如下汇编代码:

 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


1.4 编译准备

点击 魔法棒 ,在 Output 界面下,勾选 Create HEX File ,点击OK,才能生成 hex 文件;
在这里插入图片描述

1.5 编译

(1)点击图标编译工程;
在这里插入图片描述
(2)生成hex文件,编译结果如下(警告可忽略):
在这里插入图片描述

2 分析编译生成的Hex文件

2.1 生成的hex文件

(1)最终生成的 hex 文件的各段大小
在这里插入图片描述
(2)用记事本打开 hex 文件,都是一连串的十六进制
在这里插入图片描述

2.2 分析hex文件

2.2.1 何为hex文件

(1)hex文件

  • Intel HEX文件是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。Intel HEX文件通常用于传输将被存于ROM或者EPROM中的程序和数据。大多数EPROM编程器或模拟器使用Intel HEX文件。

(2)数据格式

  • Intel HEX由任意数量的十六进制记录组成。每个记录包含5个域,它们按以下格式排列::llaaaatt[dd...]cc
  • 每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数字
  • 每一个域由至少两个十六进制编码数字组成,它们构成一个字节,就像以下描述的那样:
字母含义
每个Intel HEX记录都由冒号开头
ll是数据长度域,它代表记录当中数据字节(dd)的数量
aaaa是地址域,它代表记录当中数据的起始地址
tt是代表HEX记录类型的域,它可能是以下数据当中的一个:(00-数据记录、01-文件结束记录、02-扩展段地址记录、04-扩展线性地址记录)
dd是数据域,它代表一个字节的数据。一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域(ll)中指定的数字相符
cc是校验和域,它表示这个记录的校验和。校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足

记录格式可表示为:“:[1字节长度][2字节地址][1字节记录类型][n字节数据段][1字节校验和]

2.2.2 对生成的hex文件分析

(1)扩展线性地址记录

  • 扩展线性地址记录也叫作32位地址记录或HEX386记录 , 这些记录含数据的高16位。扩展线性地址记总是有两个数据字节 , 外观如下(上述工程所生成的hex文件):
    :020000040800F2
    在这里插入图片描述
数据分析
02记录当中数据字节的数量
0000是地址域,对于扩展段地址记录,这个域总是0000
04记录类型 04( 扩展线性地址记录)
0800地址的高 16 位
F2是这个记录的校验和,计算方法:01h+NOT(02h+00h+00h+04h+08h+00h)
  • 当一个扩展线性地址记录被读取,存储于数据域的扩展线性地址被保存,它被应用于从Intel HEX文件读取来的随后的记录。线性地址保持有效,直到它被另外一个扩展地址记录所改变。
  • 通过把记录当中的地址域与被移位的来自扩展线性地址记录的地址数据相加获得数据记录的绝对存储器地址。

(2)数据记录
在这里插入图片描述

  • 第二行是数据记录,里面的地址值是0x0000。那么数据1D000A00000000000000000000000000(共16个字节)要写入FLASH中的地址为 (0x00008000<< 16)| 0x0000,也就是写入FLASH的0x80000000这个地址。
  • 第三行的数据写入地址为0x80000010。当一个HEX文件的数据超过64k的时候,文件中就会出现多个扩展线性地址记录。

(3)文件尾

  • Intel HEX文件必须以文件结束(EOF)记录结束这个记录的记录类的值必须是01。EOF记录外观总是如下(位于hex文件最后一排):
    :00000001FF
    在这里插入图片描述
数据分析
00记录当中数据字节的数量
0000数据被下载到存储器当中的地址,在文件结束记录当中地址是没有意义、被忽略的。(0000h 是典型的地址)
01记录类型 01(文件结束记录)
FF是这个记录的校验和,计算方法如下: 256D-(00H+00H+00H+01H)=FFH

3 仿真调试

3.1 仿真调试前准备

  • 点击魔法棒,调出Options for Target 'Target 1'界面,在其中点击Debug;
  • 选中Use Simulator,选中Run to main(); 在下面的Dialog DLL:空白处填入DARMSTM.DLL,在Parameter:空白处填入-pSTM32F103VE(此处芯片名称与上述工程选择的芯片名称必须一致);
  • 最后点击OK,准备完成
    在这里插入图片描述

3.2 进入调试模式

  • 点击下图表示标识,将进入调试模式;
    在这里插入图片描述

  • 可以看到,此时,寄存器R0,R1,R2,R3,R5,R6,R7,R8的值和程序设置不一致,具体如下图所示:
    在这里插入图片描述

  • 接着进行断点调试,最后可以看到,结果符合预期,寄存器R5R6R7R8的值和程序设置一致,具体如下图所示:
    在这里插入图片描述

4 总结

首次接触这种汇编方式,也相当于是个新手,好在通过理解和参考完成了,大体熟悉了各种软件的操作和汇编语言的创建。在仿真调试时,也重温了一回断点调试,体验了在没有硬件条件下进行仿真调试来观察ARM寄存器的变化状况。实验操作整体不错,往后继续努力吧。

5 参考资料

1、ARM汇编基础之基于MDK创建纯汇编语言的STM32工程
2、hex文件格式学习记录
3、搜狗百科:hex文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值