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

文章目录

  • 一、创建一个新工程
  • 二、环境配置
  • 三、添加源文件
  • 四、编写汇编程序
    • 1.代码
    • 2.仿真器设置
  • 五、仿真调试
  • 六、分析HEX文件
  • 七、总结
  • 八、参考资料

一、创建一个新工程

双击打开已经安装好的Keil uVision5(或者其他版本),点击菜单栏Project->New uVision Project,新建项目,在弹窗中设置工程项目的名称和路径,在这里,设置新建工程名为LED的文件。
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第1张图片
如下图在对应路径,工程文件已经创建成功
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第2张图片

二、环境配置

选择设备:
在弹窗中选择相应的目标环境,此处我选的是STM32F103ZE
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第3张图片
选择运行环境:
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第4张图片

三、添加源文件

  • 右击 Source Group 1,点击Add New Item to Group ‘Source Group 1’…
    基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第5张图片
  • 点击 Asm Files (.s) 添加汇编文件,然后输入文件名(Test),并点击 Add
    基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第6张图片
    基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第7张图片
    自此,出现如上界面,添加文件的过程就完成了,就可以开始编写汇编程序。

四、编写汇编程序

1.代码

 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.仿真器设置

点击菜单中的Project,找到Options for Target ‘Target 1’并点击,选择Debug–>Use Simulator,将Dialog DLL以及Parameter处修改为自己选择的设备,再点击OK,如下图所示:
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第8张图片
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第9张图片
再点击Output,将Create HEX File 勾选上,以生成HEX文件,点击OK
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第10张图片

五、仿真调试

按照下图所示们进行编译仿真:
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第11张图片
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第12张图片
基于MDK创建纯汇编语言的STM32工程并分析HEX文件内容_第13张图片
可以看到寄存器R5、R6、R7、R8的值和程序设置的一样。

六、分析HEX文件

.hex文件是什么:

它是由一行行符合Intel HEX 文件格式的文本所构成的ASCII 文本文件。每一行包含一 个 HEX 记录 ,由对应机器语言码和/或常量数据的十六进制编码数字组成。Hex文件通常用于传输将被存于ROM 或者EPROM 中的程序和数 据。大多数EPROM 编程器或模拟器使用Intel HEX 文件。Hex文件是可以烧写到单片机中,被单片机执行的一种文件格式,生成Hex文件的方式由很多种,可以通过不同的编译器将C程序或者汇编程序编译生成hex。

.hex文件的数据格式:
在这里插入图片描述

Intel HEX 由任意数量的十六进制记录组成。每个记录包含5个域,每一组字母 对应一个不同的域,每一个字母对应一个十六进制编码的数字。每一个域由至少两个十六进制编码数字组成,它们构成一个字节。

  • **:**每个Intel HEX 记录都由冒号开头;
  • LL 是数据长度域, 它代表记录当中数据字节 (D…D) 的数量;
  • aaaa 是地址域, 它代表记录当中数据的起始地址;
  • TT是代表HEX 记录类型的域 , 它可能是以下数据当中的一 个:

00: 数据记录(Data Record),用来记录数据,HEX文件的大部分记录都是数据记录。
01: 文件结束记录(End of FileRecord),用来标识文件结束,放在文件的最后,标识HEX文件的结尾。
02: 扩展段地址记录(ExtendedSegment Address Record),用来标识扩展段地址的记录,扩展段地址记录(HEX86),它包含4~19位数据地址段。由于普通的Intel的HEX记录文件只能记录64K的地址范围,所以大于64K的地址数据要靠扩展段地址记录。
03: 开始段地址记录(Start Segment Address Record)
04: 扩展线性地址记录(Extended Linear Address Record),用来标识扩展线性地址的记录,扩展线性地址记录也叫32位地址记录或者HEX386记录,这些记录包含了数据在存储器里真实地址的高16位。 当一个扩展线性地址记录被读取后,将一直保持有效,直到它被另一个扩展地址记录改变。因为它记录的是后面数据在存储器里存放的真实起始地址,所以它的起始地址偏移量(Load offset)总是0000。
05: 开始线性地址记录(Start Linear Address Record),32位机(80386或更高的CPU)的EIP寄存器里存放的地址(main函数的入口地址)。

  • D…D是数据域,它代表一个字节的数据。一个记录可以有许多数据字节。记录当中数据字节的数量必须和数据长度域(LL)中指定的数字相符。
  • CC是校验和域,它表示这个记录的校验和。校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足。

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

以前文生成的hex文件为例:

:020000040800F2
:100000000006002031010008390100083B0100080A
:100010003D0100083F010008410100080000000008
:100020000000000000000000000000004301000884
:1000300045010008000000004701000849010008D0
:100040004B0100084B0100084B0100084B01000860
:100050004B0100084B0100084B0100084B01000850
:100060004B0100084B0100084B0100084B01000840
:100070004B0100084B0100084B0100084B01000830
:100080004B0100084B0100084B0100084B01000820
:100090004B0100084B0100084B0100084B01000810
:1000A0004B0100084B0100084B0100084B01000800
:1000B0004B0100084B0100084B0100084B010008F0
:1000C0004B0100084B0100084B0100084B010008E0
:1000D0004B0100084B0100084B0100084B010008D0
:1000E0004B0100084B0100084B0100084B010008C0
:1000F0004B0100084B0100084B0100084B010008B0
:100100004B0100084B0100084B0100084B0100089F
:100110004B0100084B0100084B0100084B0100088F
:100120004B0100084B0100084B0100084B0100087F
:100130000948804709480047FEE7FEE7FEE7FEE77B
:10014000FEE7FEE7FEE7FEE7FEE7FEE704480549B7
:10015000054A064B7047000041020008990200085A
:100160000000002000060020000200200002002005
:10017000704770477047000080B500F001F880BDFF
:1001800082B041F204000021C4F20200019100910A
:1001900050F8041C41F4803140F8041C50F8041C51
:1001A00001F400310091019901310191009919B9CF
:1001B0000199B1F5A06FF1D150F8041C890354BF27
:1001C0000021012100910099012936D142F200015C
:1001D000C4F202010A6842F010020A600A6822F0C2
:1001E00003020A600A6842F002020A6001680160C4
:1001F00001680160016841F480610160016821F4D7
:100200007C110160016841F4E811016050F8041CA0
:1002100041F0807140F8041C50F8041C8901FBD5A2
:10022000016821F003010160016841F002010160F1
:10023000016801F00C010829FAD102B070470000F2
:1002400080B541F20000C4F202000168002241F0D2
:10025000010101604168CFF6FF0211404160016871
:100260004FF6FF72CFF6F66211400160016821F48B
:1002700080210160416821F4FE0141604FF41F01BB
:100280008160FFF779FF4EF60850CEF200004FF084
:100290000061016080BD00004FF00A004FF00B01CB
:1002A0004FF00C024FF00D0300F009F800F00AF8CF
:1002B00000F00BF8DFF81CE0DFF81CF0FEE74FF071
:1002C000050570474FF0060670474FF007074FF0DF
:0C02D00008087047BF020008CB020008BD
:040000050800029954
:00000001FF

该文件为16进制的一串字符。hex文件的第一排字符称之为扩展线性地址记录,也称为32位地址记录HEX386记录
在第一行数据020000040800F2中,其实际表达为0x02 0x00 0x00 0x04 0x08 0x00 0xf2。具体含义为:
1.第一个字节 0x02 表示本行数据的长度;
2.第二三字节 0x00 0x00 表示本行数据的起始地址;
3.第四字节 0x04 表示数据类型;
4.然后是数据 0x08 0x00;
5.最后一个字节 0xf2 为检验和。

七、总结

通过本次实验,基本了解了MDK编译STM32工程的基本流程,并了解了HEX文件内容和知道了使用仿真器模式调试时要根据选择的设备更改参数。

八、参考资料

https://blog.csdn.net/qq_43279579/article/details/111717607
https://blog.csdn.net/qq_45659777/article/details/120496577
https://blog.csdn.net/ssj925319/article/details/111868500
https://blog.csdn.net/u010632165/article/details/106481146
https://blog.csdn.net/xwmrqqq/article/details/111824539

你可能感兴趣的:(stm32,arm,嵌入式硬件)