一、stm32汇编程序
1.新建工程
双击打开keil,点击菜单栏Project–>New μVision Project,新建项目,在弹窗中设置工程项目的名称和路径,在这里,我新建名为test的工程文件。
2.环境配置
keil的环境搭建以及调试步骤已经在之前博客提到
https://blog.csdn.net/qq_52187415/article/details/127121055
添加源文件
右键单击Source Group 1,选择Add New Item to Group,添加Asm File (.s)文件,命名为main并保存。
加入汇编代码:
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
3.调试编译
设置仿真器模式
点击菜单中的Project,找到Options for Target ‘Target 1’并点击,选择Debug–>Use Simulator,将Dialog DLL以及Parameter处修改为自己选择的设备,OK。
编译调试
选中带有红色d的放大镜开始调试,在②处就是仿真调试所需要的调试工具。
开始调试
可以看见寄存器R5,R6,R7,R8的值和程序设置一样。
二、分析HEX文件
:020000040800F2
:1000000000060020ED000008F5000008F7000008D9
:10001000F9000008FB000008FD00000800000000D7
:10002000000000000000000000000000FF000008C9
:10003000010100080000000003010008050100089C
:100040000701000807010008070100080701000870
:100050000701000807010008070100080701000860
:100060000701000807010008070100080701000850
:100070000701000807010008070100080701000840
:100080000701000807010008070100080701000830
:100090000701000807010008070100080701000820
:1000A0000701000807010008070100080701000810
:1000B0000701000807010008070100080701000800
:1000C00007010008070100080701000807010008F0
:1000D00007010008070100080701000807010008E0
:1000E00007010008070100080701000809488047C8
:1000F00009480047FEE7FEE7FEE7FEE7FEE7FEE70A
:10010000FEE7FEE7FEE7FEE704480549054A064B21
:100110007047000061020008C902000800000020CA
:1001200000060020000200200002002070477047F7
:100130007047000080B500F001F880BD84B0002059
:100140000390029041F20001C4F20201086840F4F9
:1001500080300860FFE741F20000C4F2020000684E
:1001600000F400300290039801300390FFE70299F9
:100170000020019039B9FFE70398B0F5A06018BFDF
:1001800001200190FFE70198C0070028E3D1FFE7B5
:1001900041F20000C4F2020000688003002803D589
:1001A000FFE70120029002E000200290FFE70298A2
:1001B000012851D1FFE742F20001C4F202010868B0
:1001C00040F010000860086820F007000860086828
:1001D00040F00200086041F20401C4F20201009103
:1001E0000868086008680860086840F48060086073
:1001F000086820F47C100860086840F4E810086083
:1002000041F20001C4F20201086840F08070086009
:10021000FFE741F20000C4F20200006880010028FC
:1002200001D4FFE7F5E741F20401C4F202010868D6
:1002300020F003000860086840F002000860FFE753
:1002400041F20400C4F20200006800F00C0008282B
:1002500001D0FFE7F4E700E0FFE704B070470000DB
:1002600080B541F20002C4F20202106840F00100C1
:10027000106041F20401C4F2020108680023CFF6C5
:10028000FF031840086010684FF6FF73CFF6F6635F
:1002900018401060106820F480201060086820F476
:1002A000FE00086041F20801C4F202014FF41F0091
:1002B0000860FFF73FFF4EF60851CEF200014FF005
:1002C0000060086080BD00004FF00A004FF00B0195
:1002D0004FF00C024FF00D0300F009F800F00AF89F
:1002E00000F00BF8DFF81CE0DFF81CF0FEE74FF041
:1002F000050570474FF0060670474FF007074FF0AF
:0C03000008087047EF020008FB0200082C
:04000005080002C924
:00000001FF
1.扩展线性地址记录
- 扩展线性地址记录(hex 文件的第一排十六进制)也叫作 32 位地址记录或 HEX386 记录
- 这些记录包含数据地址的高 16 位
- 扩展线性地址记录总是有两个数据字节,外观如下(这里我通过标记方便对应原始数据):
内容 | 描述 |
---|---|
:020000040800F2 | |
02 | 这个记录当中数据字节的数量 |
0000 | 地址域,对于扩展线性地址记录,这个域总是 0000 |
04 | 记录类型 04 (扩展线性地址记录) |
0800 | 是地址的高 16 位 |
F2 | 是这个记录的校验和,计算方法:01h + NOT(02h + 00h + 00h + 04h + 08h + 00h) |
当一个扩展线性地址记录被读取,存储于数据域的扩展线性地址被保存,它被应用于从 Intel HEX 文件读取来的随后的记录
线性地址保持有效,直到它被另外一个扩展地址记录所改变
通过把记录当中的地址域与被移位的来自扩展线性地址记录的地址数据相加获得数据记录的绝对存储器地址
2.数据部分
- Intel HEX 由任意数量的十六进制记录组成。每个记录包含 5 个域,它们按一定格式排列::llaaaatt[dd…]cc
- 每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数字
- 每一个域由至少两个十六进制编码数字组成,它们构成一个字节,就像以下描述的那样:
内容 | 描述 |
---|---|
:llaaaatt[dd…]cc | |
: | 开头 |
ll | 数据长度域,它代表记录当中数据字节(dd)的数量 |
aaaa | 地址域,它代表记录当中数据的起始地址 |
tt | 代表HEX记录类型的域,它可能是以下数据当中的一个:00(数据记录)、01(文件结束记录)、02(扩展段地址记录)、04(扩展线性地址记录) |
dd | 数据域,它代表一个字节的数据。一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域(ll)中指定的数字相符 |
cc | 校验和域,它表示这个记录的校验和(校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足) |
Intel HEX文件由任意数量以回车换行符结束的数据记录组成
实例分析:
数据 | 描述 |
---|---|
:10 000000 00060020ED000008F5000008F7000008D9 | |
10 | 这个记录当中数据字节的数量 |
0000 | 数据被加载到寄存器中的起始地址 |
00 | 记录类型(数据记录) |
00060020ED000008F5000008F7000008 | 数据信息 |
D9 | 当前数据的校验和 |
3.文件尾
在文件的最后一排,是一个文件的结束标志::00000001FF
内容 | 描述 |
---|---|
:00000001FF | |
00 | 记录长度为0 |
0000 | LOAD OFFSET为0000 |
01 | TYPE=01 |
FF | 校验和为FF |