ARM 汇编入门实践

ARM 入门实践 —— ARM 汇编

搭建 keil 开发环境

添加芯片 pack 包

keil 安装后打开界面如下:

image

点击 Pack Installer,打开界面如下:

image

image

我们使用的是 STM32F103C8T6,选择 STM32F103C8 :

image

image

由于网站在国外,所以下载较慢,请耐心等待

下载好的 pack 包如下:

image

可以在这里找到我们所需要的芯片的 pack 包,和一些需要的 CMIS文件等,点击对应的链接会跳转到官网进行下载。下载好按如下步骤进行添加:

image

选择自己需要的 pack 文件,添加好之后显示如下:

image

到此,pack 包添加完成

创建项目

点击 project 创建新项目:

image

注意:项目创建的路径中不能有中文和空格,路径中如遇到中文将无法解析,而空格可能由于系统和软件版本的不同解析为 %20

如下界面需要选择我们使用的芯片型号:

image

接下来,选择我们需要的运行环境(可以不选,到后面手动添加,但是比较麻烦,这里直接选择添加环境):

image

选择好环境之后,点击 OK ,到此项目创建完毕,项目文件如下:

image

image

STM32 程序

汇编程序

右键点击 Source Group1,然后点击如图所示:

image

汇编程序源文件的后缀是 .s ,所以添加 Asm File(.s) 文件,命名后保存(也可以直接在本地创建好 .s 文件之后进行添加):

image

汇编代码格式如下:

AREA	MAIN,	CODE,	READONLY	
; AREA 用来定义段,MAIN 是段名,CODE 表示是一个代码段,READONLY 表示段是只读
; 系统的默认入口为 RESEAT ,需要修改名字
代码正文
END	;结束标致

代码内容如下:

 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

写好代码后,我们需要进行仿真调试:

仿真调试

首先我们需要设置仿真模式,过程如下:

image

在设置窗口点击 Debug ,然后修改设置如下:

勾选 Use Simulator ,表示软件使用仿真环境测试

由于我们使用的是 USB 到 JTAG 转换盒,所以这里的调试器选择 J-LINK/J-TRACE Cortext

J-LINK、JTAG、ULINK、STLINK 区别可以参考下面这篇博客:JLINK、JTAG、ULINK和STLINK的区别介绍

勾选 Run to main() 表示跳过汇编代码,直接跳转到 main 函数开始仿真

设置 Dialog DLL 项目为 DARMSTM.DLL 和 Parameter 项目为 -pSTM32F103C8 的软硬仿真(这里选择符合自己使用的硬件和芯片的型号即可)

设置好如下图:

image

然后点击编译,查看是否有报错和警告,出现报错和警告需要及时处理并解决:

image

注意:每次修改源代码之后,需要进行 Rebuild

编译并确保没有报错和警告之后,点击进行调试:

image

点击运行后点击停止,即可得到输出数据:

image

运行结果如下,得到汇编对应的正确结果:

image

warning 解决办法

如果出现以下 warning :

.\Objects\ARM_assembly.sct(8): warning: L6314W: No section matches pattern *(InRoot$$Sections).
# 编译后会显示两个 warning ,但都是这一条

只需要打开对应的 sct 文件,将 *(InRoot$$Sections) 注释掉即可

HEX 文件

生成 Hex 文件

在 Option 中选择 Output 界面,然后将 Create HEX File 勾选上:

image

生成的 HEX 文件会保存在 Object 文件夹中:

image

HEX 文件内容如下:

:020000040800F2
:1000000000060020ED000008F5000008F7000008D9
:10001000F9000008FB000008FD00000800000000D7
:10002000000000000000000000000000FF000008C9
:10003000010100080000000003010008050100089C
:100040000701000807010008070100080701000870
:100050000701000807010008070100080701000860
:100060000701000807010008070100080701000850
:100070000701000807010008070100080701000840
:100080000701000807010008070100080701000830
:100090000701000807010008070100080701000820
:1000A0000701000807010008070100080701000810
:1000B0000701000807010008070100080701000800
:1000C00007010008070100080701000807010008F0
:1000D00007010008070100080701000807010008E0
:1000E00007010008070100080701000809488047C8
:1000F00009480047FEE7FEE7FEE7FEE7FEE7FEE70A
:10010000FEE7FEE7FEE7FEE704480549054A064B21
:10011000704700006102000835010008000000205F
:1001200000060020000200200002002070477047F7
:10013000704700004FF00A004FF00B014FF00C0227
:100140004FF00D0300F009F800F00AF800F00BF88A
:10015000DFF81CE0DFF81CF0FEE74FF00505704704
:100160004FF0060670474FF007074FF0080870473A
:100170005B0100086701000810B500F001F810BD30
:100180000CB50020019000903348006840F48030A6
:100190003149086000BF3048006800F4003000902A
:1001A0000198401C0190009818B90198B0F5A06F13
:1001B000F1D12948006800F4003010B1012000900E
:1001C00001E0002000900098012843D123480068F6
:1001D00040F01000214908600846006820F0070040
:1001E00008600846006840F0020008601A4840684D
:1001F000194948600846406848600846406840F42D
:10020000806048600846406820F47C1048600846DA
:10021000406840F4E81048600846006840F080708C
:10022000086000BF0C48006800F000700028F9D09A
:100230000948406820F003000749486008464068C4
:1002400040F00200486000BF0348406800F00C0026
:100250000828F9D10CBD0000001002400020024027
:1002600010B51348006840F00100114908600846C5
:100270004068104908400E494860084600680E4929
:1002800008400B4908600846006820F48020086098
:100290000846406820F4FE0048604FF41F00886064
:1002A000FFF76AFF4FF000600449086010BD0000CE
:1002B000001002400000FFF8FFFFF6FE08ED00E02E
:0400000508000135B9
:00000001FF

HEX 文件分析

扩展线性地址记录

扩展线性地址记录(hex 文件的第一排十六进制)也叫作 32 位地址记录或 HEX386 记录

这些记录包含数据地址的高 16 位

扩展线性地址记录总是有两个数据字节,外观如下(这里我通过标记方便对应原始数据):

:020000040800F2

内容 描述
02 这个记录当中数据字节的数量
0000 地址域,对于扩展线性地址记录,这个域总是 0000
04 记录类型 04 (扩展线性地址记录)
0800 是地址的高 16 位
F2 是这个记录的校验和,计算方法:01h + NOT(02h + 00h + 00h + 04h + 08h + 00h)

当一个扩展线性地址记录被读取,存储于数据域的扩展线性地址被保存,它被应用于从 Intel HEX 文件读取来的随后的记录

线性地址保持有效,直到它被另外一个扩展地址记录所改变

通过把记录当中的地址域与被移位的来自扩展线性地址记录的地址数据相加获得数据记录的绝对存储器地址

数据部分

Intel HEX 由任意数量的十六进制记录组成。每个记录包含 5 个域,它们按一定格式排列::llaaaatt[dd...]cc

每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数字

每一个域由至少两个十六进制编码数字组成,它们构成一个字节,就像以下描述的那样:

:llaaaatt[dd…]cc

内容 描述
: 每个Intel HEX记录都由冒号开头
aaaa 地址域,它代表记录当中数据的起始地址
tt 代表HEX记录类型的域,它可能是以下数据当中的一个:00(数据记录)、01(文件结束记录)、02(扩展段地址记录)、04(扩展线性地址记录)
dd 数据域,它代表一个字节的数据。一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域(ll)中指定的数字相符
cc 校验和域,它表示这个记录的校验和(校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足)

文件尾

在文件的最后一排,是一个文件的结束标志:

:00000001FF

内容 描述
00 记录的长度为 0
0000 LOAD OFFSET 为 0000
01 TYPE = 01
FF 校验和为 FF

参考资料

1.Keil环境下创建STM32汇编语言工程并分析HEX文件内容

2.基于Keil5创建STM32汇编语言工程以及hex文件分析

posted @ 2022-10-01 10:14  ppqppl  阅读(237)  评论(0编辑  收藏  举报