自己的学习工作日志,比较杂,各位勿怪
1、BSS data text段
2、LDM指令等指令
3.堆栈寻址方式,依次讲解STMFD、STMED、STMFA、STMEA
4、最小计算机系统
bss段:bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域 。
bss是英文Block Started by Symbol的简称 。
bss段属于静态内存分配 。
data段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域 。
数据段属于静态内存分配 。
text段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域 。
这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写 , 即允许修改程序) 。
在代码段中,也有可能包含一些只读的常数变量 , 例如字符串常量等 。
堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减 。
当进程调用malloc等函数分配内存时 , 新分配的内存就被动态添加到堆上(堆被扩张);
当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减) 。
栈(stack):栈又称堆栈,是用户存放程序临时创建的局部变量 ,
也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量) 。
除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中 。
由于栈的先进先出(FIFO)特点,所以栈特别方便用来保存/恢复调用现场 。
从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区 。
一个程序本质上都是由 bss段、data段、text段三个组成的 。
这样的概念,不知道最初来源于哪里的规定,但在当前的计算机程序设计中是很重要的一个基本概念 。
而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题 。
在采用段式内存管理的架构中(比如intel的80x86系统),bss段通常是指用来存放程序中未初始化的全局变量的一块内存区域 ,
一般在初始化时bss 段部分将会清零 。bss段属于静态内存分配,即程序一开始就将其清零了 。
比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中 , 未初始化的全局变量保存在.bss 段中 。
text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中) , 由系统从可执行文件中加载;
而bss段不在可执行文件中,由系统初始化 。
【例】两个小程序如下:程序1:
int ar[30000];void main(){......}程序2:
int ar[300000] = {1, 2, 3, 4, 5, 6 };void main(){......}发现程序2编译之后所得的.exe文件比程序1的要大得多 。当下甚为不解,于是手工编译了一下,并使用了/FAs编译选项来查看了一下其各自的.asm,
发现在程序1.asm中ar的定义如下:
_BSS SEGMENT?ar@@3PAHA DD 0493e0H DUP (?) ; ar_BSS ENDS而在程序2.asm中,ar被定义为:
_DATA SEGMENT?ar@@3PAHA DD 01H ; arDD 02HDD 03HORG $+1199988_DATA ENDS区别很明显,一个位于.bss段,而另一个位于.data段,两者的区别在于:
全局的未初始化变量存在于.bss段中,具体体现为一个占位符;
全局的已初始化变量存于.data段中;
而函数内的自动变量都在栈上分配空间;
.bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);
.data却需要占用 , 其内容由程序初始化 。因此造成了上述情况 。
【嵌入式u stm是什么意思】bss段(未手动初始化的数据)并不给该段的数据分配空间 , 只是记录数据所需空间的大?。?
bss段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段后面 。
data段(已手动初始化的数据)则为数据分配空间,数据保存在目标文件中;
data段包含经过初始化的全局变量以及它们的值 。当这个内存区进入程序的地址空间后全部清零 。
包含data段和bss段的整个区段此时通常称为数据区 。
2、LDM指令等指令
关于多寄存器加载存储指令
1.LDMIA指令、LDMIB指令、LDMDB指令、LDMDA指令
(1)LDMIA指令 , IA表示每次传送后地址加4
文章插图
(2)LDMIB指令 , 每次传送前地址加四
文章插图
(3)LDMDB指令,每次传送前地址减4,这里还要注意程序中先给R5,还是先给R8,这里明显是先给R8 。
文章插图
(4)LDMDA指令,每次传送后地址减4,这里也是先给R8,不是先给R5!
文章插图
下面来看看STMIA指令、STMIB指令、STMDB指令、STMDA指令
(1) STMIA指令, STMIA R0,{R1,R2,R3,R4} ;将R1—R4的数据存储到R0指向的地址上,R0的值不更新,IA传送后地址加4 , 所以这里内存当中的地址是从0x8004开始变化的
文章插图
(2) STMIB指令, STMIB R0,{R1,R2,R3,R4} ;将R1—R4的数据存储到R0指向的地址上,R0的值不更新,IB每次传送前地址加4 , 所以内存中的值是从0x8008开始变化的
文章插图
3) STMDB指令, STMDB R0,{R1,R2,R3,R4} ;将R1—R4的数据存储到R0指向的地址上,R0的值更新,DB每次传送后地址减4,所以内存中的值是从0x8010开始递减变化的,注意这里是先把表达式中的R4先给地址0x8010
文章插图
(4) STMDA与上面STMDB指令类似 , DA是每次传送后地址减4,我就不截图了 。
3.堆栈寻址方式,依次讲解STMFD、STMED、STMFA、STMEA(1) STMFD意思是满堆栈递减指令,堆栈向下增长 。如下图就是解释堆栈向上增长,向下增长,栈顶指针在内存中向低地址处移动,叫做向下增长,这里我为什么要先讲STMFD指令 , 怎么不讲LDMFD等指令呢,因为这里涉及到堆栈,向内存中写入寄存器中所存储的值,更能体现出进栈的动作,看完下面的例子,你会知道STM的后缀为什么是FD了 。
文章插图
关键代码:STMFDSP!,{R1-R3,R4},可以这么看 , 先把R4,R3,R2,R1依次压栈,至于为什么不是R1,R2,R3,R4依次压栈,因为做出的实验就不是这样的,所以R4准备进栈的时候,栈指针SP先减4,然后先把R4寄存器里面的值放到内存地址为0x803c里面,这里为什么SP要先减4呢,因为这里是满堆栈 , 所以要先把栈指针做出响应的变化以后,才能进行存储,至于什么是满堆栈和空堆栈 , 我这里就不解释了 。程序效果看下图即可:
文章插图
(2) 看了上面STMFD以后,现在看STMFA(满递增堆栈)就很简单了:不过这里需要特别注意,这里并不是先操作R4寄存器的,而是操作R1寄存器,同理的是,先把SP做相应的改变 , 也就是这里先SP+4=0x8044,然后把R1寄存器的值放到内存地址的0x8044处 , 然后R2 , R3,R4依次放下去,最后改变SP的值 , 因为代码中多了一个感叹号STMFA SP!,{R1-R3,R4}
文章插图
(3) STMED是空递减堆栈 , 可以看出堆栈指针一开始指在0x8040处,所以先把R4的寄存器的值放到内存单元0x8040中,这里其实也是先操作R4寄存器,至于为什么,只能说和STMFD对应的 。
文章插图
(4) STMEA空递增堆栈,根据堆栈的指令意思理解和试验结果对应
文章插图
下面看看和STMFD指令相对应的LDMFD等指令,我依次讲解LDMFD、LDMFA、LDMED、LDMEA指令,至于我为什么按这种顺序讲 , 为了和上面的STMFD等指令联系在一起 。(1) 还记得我上面那些STM那些指令先将的是什么,对了,第一个讲的是STMFD指令,把内存中的数据批量放到寄存器中 。FD为满递减堆栈 。
这里值得注意的是,FD不是满堆栈递减吗,为什么程序执行完以后SP是增加的,在没有执行MOVR9, SP这条指令之前,FD确实代表是递减的意思,这里因为sp栈顶指针实际上是增加 , 至于为什么不写LDMFA,只不过这样LDMFD能和STMFD指令对应,看起来顺眼点吧,其实这里我要说明的是STMDB并不是和LDMDB对应,而是和LDMIA对应的,这里注意一下就行了,以后程序编多了,直接就记住了 , 不过你只要原理懂了,管它怎么写呢 。
文章插图
(2) 那自然地下面就讲LDMFA指令了
文章插图
3) LDMED指令
文章插图
(4) LDMEA指令
注意的一点就是这里的SP指针是我假定的一个值,如果你以后写arm代码,调用C函数的时候,用到栈指针,系统会自动分配,就不存在sp是否非法的问题,什么是非法问题呢?先举个例子 , 看下图,这里对应的SP是0x8020,并且是满递减,把寄存器的值写到内存当中,我明明写的是STMFDSP!,{R1-R3,R4},把4个寄存器的内容写到内存中,可是最后就存了两个,因为你0x8018的地址处之前可能代码段的内容就存入在那里,所以你就不能改了,获取你这时候把这个不能写入的内存地址是可以读取到寄存器中的,我没试过 , 有兴趣可以试试 。所以在用STM指令的时候要注意这点了
文章插图
4、最小计算机系统
硬件最小系统:由电源、主板和CPU、内存组成.在这个系统中 , 没有任何信号线的连接,只有电源到主板的电源连接.在判断的过程中通过声音来判断这一核心组成部分是否可正常工作:
软件最小系统:由电源,主板,CPU.内存,显示卡/显示器 。键盘和硬盘组成.这个最小系统主要用来判断系统是否可完成正常的启动与运行 。
1. 硬盘中的软件环境保留原有的软件环境,主要是用来分析判断应用软件方面的问题.
2. 硬盘中的软件环境只有一个基本的操作系统环境<可能是卸载掉所有应用,或是重新安装一个干净的操作系统环境,是要判断系统问题,软件冲突或软硬件间的冲突问题.
3. 在软件最小系统下,可根据需要添加或更改适当的硬件.如:在判断启动故障时,由于硬盘不能启动.想检查一下能否从其它驱动器启动.这时,可在软件最小系统下加入一个软驱或最小系统中加入声卡;在判断网络问题时,就应在软件最小系统中加入网卡等.最小系统法,主要地要先判断在最基本的软硬件环境中,系统是否可正常工作如果不能正常工作,却可判定最基本的软硬部件有故障,从而起到故障隔离的作用.
最小系统法逐步添加法结合,能较快速地定位发生在其它板软件的故障,提高维修效率
- 一文读懂四大AMC和地方AMC前世今生 四大AMC是什么
- 当之无愧是什么意思_当之无愧的意思是什么?
- 归省的意思_荏苒是什么意思?
- 归去凤池夸_异日图将好景,归去凤池夸。这句诗的译文是什么意思?
- 强调的意思_至少是什么意思强调了什么
- 教师的职责和使命 教师的职责和使命是什么
- 美容师培训课程内容 美容师培训课程内容是什么
- 成语安步当车表达的意思是 成语安步当车表达的意思是什么
- 屈原 兮是什么意思和含义
- 强烈的近义词_“强劲”的近义词是什么?
