加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ARM开发总结的小知识

发布时间:2020-12-15 18:37:54 所属栏目:百科 来源:网络整理
导读:ARM开发总结的小知识 字节 8位 半字 16位 字?? 32位 ? Code,RO-data RW-data,ZI-data ? Code为程序代码部分 RO-data 表示程序定义的常量 const temp; RW-data 表示已初始化的全局变量 ZI-data 表示未初始化的全局变量 ? Program Size: Code="18248"RO-data=3

ARM开发总结的小知识

字节 8位

半字 16位

字?? 32位

?

Code,RO-data

RW-data,ZI-data

?

Code为程序代码部分

RO-data 表示程序定义的常量 const temp;

RW-data 表示已初始化的全局变量

ZI-data 表示未初始化的全局变量

?

Program Size: Code="18248"RO-data=320 RW-data=260 ZI-data=3952?

?

Code,RO-data,RW-data ..............flash

RW-data,ZIdata...................RAM

?

初始化时RW-data从flash拷贝到RAM

?

生成的map文件位于list文件夹下 (KEIL)

?

???Total RO? Size (Code + ROData)??????????????? 18568 (? 18.13kB)

???Total RW? Size (RW Data + ZIData)????????????? 4212 (?? 4.11kB)

???Total ROM Size (Code + RO Data + RW Data)????? 18828 (?18.39kB)

?

ARM指令的长度刚好是1个字(分配为占用4个字节),Thumb指令的长度刚好是半字(占用2个字节)

?

R0-R15 (R15-PC,R14-LR,R13-SP) 32位

?

每个异常模式还带有一个程序状态保存寄存器 (SPSR),它用于保存在异常事件发生之前的CPSR

?

LDMIA R1!,{R2-R7,R12} ;将R1单兀中的数据读出到R2-R7,R12,? R1自动加1

STMIA RO!,{R3-R6,R10}? ;将R3-R6,R10中的数据保存到RO指向的地址,RO自动加1

?

在数据传送之前,将偏移量加到Rn中,其结果作为传送数据的存储地址.若使用后缀“!”,则结果写回到Rn中,且Rn值不允许为R15.指令举例如下:

LDR??Rd,[Rn,#Ox4]!

?

LDMFD?SP!,{R0-R3,PC}^ ;中断返回

“^”符号表示这是一条特殊形式的指令。这条指令在从存储器中装载PC的同时(PC是最后恢复的),CPSR也得到恢复

?

大端格式(Big-endian)

小端格式(Little-endian)

?

数据0x12345678存储格式

?????大端格式

低地址<----0x12|0x34|0x56|0x78---->高地址

?????小端格式

低地址<----0x78|0x56|0x34|0x12---->高地址

?

ARM微处理器支持7种运行模式,分别为:CPSR M[4:0]

?

用户模式(usr):ARM处理器正常的程序执行状态。?? 10000

快速中断模式(fiq):用于高速数据传输或通道处理。 10001

外部中断模式(irq):用于通用的中断处理。???????????? 10010

管理模式(svc):操作系统使用的保护模式。??????????? 10011

数据访问终止模式(abt):当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护。10111

系统模式(sys):运行具有特权的操作系统任务。 22222

定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真。11011

?

ARM正常工作一般工作在用户模式和系统模式,复位的时候进入管理模式

?

对于ARM指令集来说,PC指向当前指令的下两条指令的地址

?

注意pc,在调试的时候显示的是当前指令地址,而用mov lr,pc的时候lr保存的是此指令向后数两条指令的地址

?

假设反汇编代码:? 0x000001 :?mov lr pc???

?

(此时查看PC寄存器的值是0x000001,但实际PC值是0x000003,lr里面保存的就是0x000003)

?

fields 指定传送的区域(psr? CPSR或SPSR)

c 控制域屏蔽字节(psr[7..0])

x 扩展域屏蔽字节(psr[15..8])

s 状态域屏蔽字节(psr[23..16])

f 标志域屏蔽字节(psr[31..24])

?

例如:MSR cpsr_c,#0xD3 ;? CPSR[7...0] = 0xD3

?

CODE SIZE,RO DATA,RW DATA,ZI DATA,idata,pdata---project Map 文件解读(一)

????optimization project时,开始往往是关注一时间性能,如codec mips或MCPS等。当时间性能达到了要求时,往往还会加入size这一参数来作比较,这时就要考虑各种各样的size。这一性能参数可能在projectrequirements book中有明显的说明,在testperformance result或在release note中也有更加准备的数据记录。

?

??? 如下表:

?

Program ROM???????? Data RAM ROM Table

Scratch?Stack Static

XX XX XX XX XX

?

?

??? 首先我们要弄清楚这些size的含义以及所反应的性能意义。

?

?? 1、CODE SIZE,ZIDATA

?

?? 上面这些变量是在ARM 开发环境下会出现的数值,可以在armlink中加一些参数,得到相应有.map文件,从中就能准确的获取这些值,有一篇文章详细说明这些含义:

?

? ARM程序(指在ARM系统中正在执行的程序,而非保存在ROM中的bin文件)的组成

一个ARM程序包含3部分:RO段,RW段和ZI段

RO是程序中的指令和常量

RW是程序中的已初始化变量

ZI是程序中的未初始化的变量

由以上3点说明可以理解为:

RO就是readonly,

RW就是read/write,

ZI就是zero

ARM映像文件的组成

所谓ARM映像文件就是指烧录到ROM中的bin文件,也成为image文件。以下用Image文件来称呼它。

Image文件包含了RO和RW数据。

之所以Image文件不包含ZI数据,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。

Q:为什么Image中必须包含RO和RW?

A:因为RO中的指令和常量以及RW中初始化过的变量是不能像ZI那样“无中生有”的。

ARM程序的执行过程

从以上两点可以知道,烧录到ROM中的image文件与实际运行时的ARM程序之间并不是完全一样的。因此就有必要了解ARM程序是如何从ROM中的image到达实际运行状态的。

实际上,RO中的指令至少应该有这样的功能:

1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。

2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中

在程序运行的最初阶段,RO中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。

说了上面的可能还是有些迷糊,RO,RW和ZI到底是什么,下面我将给出几个例子,最直观的来说明RO,RW,ZI在C中是什么意思。


1; RO
看下面两段程序,他们之间差了一条语句,这条语句就是声明一个字符常量。因此按照我们之前说的,他们之间应该只会在RO数据中相差一个字节(字符常量为1字节)。
Prog1:
#include <stdio.h>
void main(void)
{
;
}
Prog2:
#include <stdio.h>
const char a = 5;
void main(void)
{
;
}
Prog1编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog2编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 61 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1009 ( 0.99kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
以上两个程序编译出来后的信息可以看出:
Prog1和Prog2的RO包含了Code和RO Data两类数据。他们的唯一区别就是Prog2的RO Data比Prog1多了1个字节。这正和之前的推测一致。
如果增加的是一条指令而不是一个常量,则结果应该是Code数据大小有差别。

2; RW
同样再看两个程序,他们之间只相差一个“已初始化的变量”,按照之前所讲的,已初始化的变量应该是算在RW中的,所以两个程序之间应该是RW大小有区别。
Prog3:
#include <stdio.h>
void main(void)
{
;
}
Prog4:
#include <stdio.h>
char a = 5;
void main(void)
{
;
}
Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 1 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB)
================================================================================
可以看出Prog3和Prog4之间确实只有RW Data之间相差了1个字节,这个字节正是被初始化过的一个字符型变量“a”所引起的。

3; ZI
再看两个程序,他们之间的差别是一个未初始化的变量“a”,从之前的了解中,应该可以推测,这两个程序之间应该只有ZI大小有差别。
Prog3:
#include <stdio.h>
void main(void)
{
;
}
Prog4:
#include <stdio.h>
char a;
void main(void)
{
;
}
Prog3编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 96 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 96 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
Prog4编译出来后的信息如下:
================================================================================
Code RO Data RW Data ZI Data Debug
948 60 0 97 0 Grand Totals
================================================================================
Total RO Size(Code + RO Data) 1008 ( 0.98kB)
Total RW Size(RW Data + ZI Data) 97 ( 0.09kB)
Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB)
================================================================================
编译的结果完全符合推测,只有ZI数据相差了1个字节。这个字节正是未初始化的一个字符型变量“a”所引起的。
注意:如果一个变量被初始化为0,则该变量的处理方法与未初始化华变量一样放在ZI区域。
即:ARM C程序中,所有的未初始化变量都会被自动初始化为0。
总结:
1; C中的指令以及常量被编译后是RO类型数据。
2; C中的未被初始化或初始化为0的变量编译后是ZI类型数据。
3; C中的已被初始化成非0值的变量编译后市RW类型数据。
附:
程序的编译命令(假定C程序名为tst.c):
armcc -c -o tst.o tst.c
armlink -noremove -elf -nodebug -info totals -info sizes -map -list aa.map -o tst.elf tst.o
编译后的信息就在aa.map文件中。
ROM主要指:NAND Flash,Nor Flash
RAM主要指:PSRAM,SDRAM,SRAM,DDRAM


?

???? 具体的链接:http://hi.baidu.com/whyspai/blog/item/d1815fa99c3da6fb1e17a283.html

?

?

?

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/winmenaruto/archive/2011/03/17/6256770.aspx

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读