历史上的今天
返回首页

历史上的今天

今天是:2025年03月08日(星期六)

2020年03月08日 | 【ARM裸板】启动文件与栈的简略分析

2020-03-08 来源:eefocus

1.start.S过程

设置栈

调用main函数,并把返回地址保存在LR(R14)中

.text

.global _start

_start:

/* 设置内存: sp栈 */

ldr sp, = 4096 /* nand 启动 */

/* 调用main函数 */ 

bl main 

halt:

b halt


2.led.c过程

定义两个局部变量

设置变量

return 0

int main(void)

{

volatile unsigned int *pGPFCON = (volatile unsigned int *)0x56000050;

volatile unsigned int *pGPFDAT = (volatile unsigned int *)0x56000054;

*pGPFCON = 0x100;

*pGPFDAT = 0;

return 0;

}


3.问题

函数的调用规则ATPCS:ARM-THUMB procedure call standard(ARM-Thumb过程调用标准)

参考文章 Arm汇编学习笔记(六)——函数调用栈空间以及fp寄存器


3.1 为什么要设置栈?

因为C函数所需

保存局部变量

保存LR等寄存器(返回地址)

在这里插入图片描述

调用者如何传递参数给被调用者

被调用者如何传返回这给调用者

怎么从栈中恢复那些寄存器


调用者和被调用者通过r0-r3寄存器传递参数和返回值

在函数中,r4-r11可能被使用,所以:在入口保存他们,在出口恢复他们

高标号寄存器存放在高地址


3.2 反汇编程序分析

00000000 <_start>:

   0: e3a0da01 mov sp, #4096 ; 0x1000            ;设置栈指针大小为4096

   4: eb000000 bl c

;跳转到[0x0c]main函数,并保存返回地址(下一条指令的地址,即0x08)到LR中


00000008 :

   8: eafffffe b 8


0000000c

:

   c: e52db004 push {fp} ; (str fp, [sp, #-4]!)  ;fp的值存入[4096-4](4092)中,sp = sp-4 ==> 将【栈帧底部】指针fp压入栈中;创建属于main函数的栈帧。  

  10: e28db000 add fp, sp, #0 ;fp = sp+0 = 4092+0 = 4092 ==> fp指针为函数栈帧的底部

  14: e24dd00c sub sp, sp, #12 ;sp = 4092-12 = 4080 ==> sp指针为【栈帧顶部】,同时为栈的栈顶

  18: e59f3034 ldr r3, [pc, #52] ; 54 ;r3 = [0x18+8+52] = [0x54] 

  1c: e50b3008 str r3, [fp, #-8] ;把r3(0x56000050)存放在[4084] ==> 保存局部变量

  20: e59f3030 ldr r3, [pc, #48] ; 58 ;r3 = [0x20+8+48] = [0x58]

  24: e50b300c str r3, [fp, #-12] ;把r3(0x56000054)存放在[4080] ==> 保存局部变量

  28: e51b3008 ldr r3, [fp, #-8] ;r3 = [0x4084] = 0x56000050 

  2c: e3a02c01 mov r2, #256 ; 0x100 ;r2 = 0x100

  30: e5832000 str r2, [r3] ;[r3] = 0x100 ==> 写入0x100至GPFCON寄存器

  34: e51b300c ldr r3, [fp, #-12] ;r3 = [0x4080] = 0x56000054

  38: e3a02000 mov r2, #0 ;r2 = 0

  3c: e5832000 str r2, [r3] ;[r3] = 0 ==> 写入0至GPFDAT寄存器

  40: e3a03000 mov r3, #0 ;r3 = 0 ==> return 0的返回值存放先在r3

  44: e1a00003 mov r0, r3 ;r0 = 0 ==> return 0的返回值存放在r0

  48: e28bd000 add sp, fp, #0 ;sp = fp-0 = 4092 

  4c: e49db004 pop {fp} ; (ldr fp, [sp], #4) ;fp = [4092] ==> 恢复fp,sp = sp+4 = 4096 ==>恢复栈

  50: e12fff1e bx lr ;跳转值lr寄存器所指向的地址并切换指令集

  54: 56000050 ; instruction: 0x56000050

  58: 56000054 ; instruction: 0x56000054


上面的汇编代码可以看到,并没有想上面图中所画的,将fp, sp, lr, pc全部都入栈,而是只入栈这四个寄存器中有改动的。fp是肯定要保存的,它指向的是每个函数栈帧的栈基址,而sp一般不用入栈,因为它的值一般保存在fp中,因为刚进入一个函数的时候,将上个函数的fp入栈保存以后,当前函数的栈空间应该是空的,fp应该指向与sp相同的位置,然后才会对sp做减法来分配栈空间保存临时变量。而如果当前函数中没有对其它函数的调用的时候,是不会对lr寄存器做修改的,所以也就不用保存了。

推荐阅读

史海拾趣

FRONTIER公司的发展小趣事

背景:虽然此处的FRONTIER可能指的是边疆通信公司(Frontier Communications),但为符合电子行业背景,我们假设其在农村宽带服务方面的创新。

发展故事:在21世纪初期,FRONTIER Communications认识到农村地区对于宽带服务的迫切需求,于是开始大规模投资农村宽带基础设施建设。通过引入先进的通信技术和设备,FRONTIER Communications成功地将高速互联网带到了偏远地区,极大地改善了当地居民的生活和工作条件。这一举措不仅赢得了市场的广泛赞誉,也为公司带来了稳定的收入来源和持续增长的动力。

Advanced Electronic Packaging公司的发展小趣事

随着公司技术的不断进步,Advanced Electronic Packaging公司开始寻求与行业内知名厂商的合作机会。通过与一家全球领先的电子产品制造商达成战略合作,公司成功将其先进的封装技术应用于对方的高端产品线中。这一合作不仅提升了合作双方的产品竞争力,还为Advanced Electronic Packaging公司带来了可观的利润回报。此后,公司陆续与多家知名企业建立了合作关系,进一步巩固了其在电子封装领域的市场地位。

DESCO公司的发展小趣事

随着防静电产品市场的不断扩大,DESCO公司开始着手进行市场拓展和品牌塑造。公司通过参加国际展会、举办技术研讨会等方式,积极向全球客户展示其防静电产品的技术优势和应用前景。同时,DESCO还加大了品牌宣传力度,提高了品牌知名度和美誉度。这些举措为公司在全球范围内赢得了大量忠实客户,市场份额持续增长。

Black Box Corporation公司的发展小趣事

为了进一步扩大市场份额,Black Box积极寻求与全球各地的企业合作。通过与跨国公司的战略合作,Black Box不仅获得了先进的技术和管理经验,还成功打开了多个国际市场。同时,公司也在全球范围内设立了多个分公司和办事处,以便更好地服务当地客户。这一系列的全球扩张行动使Black Box成为了真正意义上的国际企业。

FORYARD公司的发展小趣事

随着业务的不断扩展,FORYARD意识到全球化布局的重要性。1995年,公司决定在中国设立研发中心和生产基地,以利用当地丰富的人才资源和成本优势。这一战略决策极大地提升了FORYARD的产能和研发效率,同时也使其能够更好地服务全球客户。此后,FORYARD还陆续在欧洲、亚洲等地建立了多个分支机构,形成了覆盖全球的研发、生产和销售网络。通过全球化布局,FORYARD不仅增强了自身的市场竞争力,还促进了全球电子产业的交流与合作。

Active-Semi公司的发展小趣事

进入21世纪后,随着新能源汽车产业的兴起,FORYARD敏锐地捕捉到了这一市场机遇。公司开始将研发重心转向汽车电子领域,特别是新能源汽车的电池管理系统(BMS)和电机控制器(MCU)等关键技术。通过持续的技术创新和研发投入,FORYARD成功开发出了一系列高性能、高可靠性的汽车电子产品,并成功应用于多家知名新能源汽车制造商的车型中。这一举措不仅为公司带来了新的增长点,也推动了新能源汽车产业的快速发展。

问答坊 | AI 解惑

电池精确测量和温度稳定的重要性

中心议题: 电池管理的常见难题精确测量的重要性解决方案: 电流测量:电量计精度的基础电流测量的度偏移电流测量:电量计精度的基锂离子电池由于拥有能量密度高、电压高、自放电率低,以及无记忆效应等优势,因而逐渐成为使用充电电池的便携应用产 ...…

查看全部问答>

100414TMS320F2812原理与开发_苏奎峰

TMS320F2812原理与开发_苏奎峰…

查看全部问答>

platform builder5.0 导出SDK 遇到的问题

用pb5.0定制了wince的内核,选择的模板是mobile handheld,bsp用的是北京博创的270S_BSP_20080918.bsp,内核到是能正常生成,在导出SDK的时候,遇到了这样的错误: Committing database changes Creating \'required\' feature Adding required ...…

查看全部问答>

camera VGA video format 能过LTK吗

LTK camera 模块测试,录象时包含有VGA分辨率,可以通过LTK测试吗?有哪位试过? 我测试时,Camera_and_DirectShow_Integration_Test中testcase 508,ASF writing tests, testing all supported video formats.跑到测试VGA时就失败了。 ???…

查看全部问答>

高分求助!!(答好了给全分)

1.中断问题 今天小弟我看到了中断这一章了, 但是到现在还搞不清楚SWI的一些地方, 特请教各位高手, 谢谢! 问题就是在加载中断这个地方    unsigned Install_Handler(unsigned routine, unsigned *vector) {    vec = (rout ...…

查看全部问答>

这个dcm究竟怎么了?

有这样两个工程—— 工程1:把输入的50MHz时钟通过dcm倍频,顶层模块除了把dcm的6个端口引出外不作任何处理。testbench里一直将dcm的对应复位脚赋0。仿真表明,倍频是成功的。 工程2:把输入的50MHz时钟通过dcm倍频。顶层模块用dcm输出的倍频信 ...…

查看全部问答>

MSP430 LaunchPad触摸板试用心得

1、硬件环境搭建 (1)、将开发板上的G2231芯片换成附赠的G2211,因为G2231不带比较器,只有G2211才带,2231带SPI和串口等 (2)、将开发板上的R34和C24焊下,焊接时小心,我就是焊接时把PCB焊坏了,这两个贴片是焊补上去了,到时只有飞线了,郁 ...…

查看全部问答>