历史上的今天
返回首页

历史上的今天

今天是:2025年02月09日(星期日)

正在发生

2021年02月09日 | 基于S3C6410的ARM11学习(十三) C语言环境初始化

2021-02-09 来源:eefocus

如今,汇编的部分,就剩下最后一步了。C语言环境初始化。因为后面的代码要用C语言来写了。毕竟C语言编写比汇编要容易对了,而且c程序具有易读性。


C程序要运行,一个最重要的东西就是栈了。因为有栈,c程序才能在程序跳转的时候,保存上文。然后在程序返回的时候,将保存的上文恢复。这样,才保证了调用函数之前和之后的上下文是不变的。


使用汇编代码写的话,是不用设置栈的,因为保护上下文是要用汇编在代码中自行写出的,而C代码是靠编译器编译自动加上的。

         栈,有4种。

    clip_image002

从图中可以看出四种栈的区别。栈都是放在内存空间的,因为要随时读写。栈的起始地址放在内存的高地址出,那么增长方向就是向下增长,这种就是递减栈。如果栈的起始地址放在内存的低地址处,那么增长方向就是向上增长,这种就是递增栈。


栈顶指针一直指向栈顶数据,就是满栈,如果一直指向栈顶的下一个数据,就是空栈。


ARM采用的是满递减栈。使用汇编对栈的操作的指令是ldmfd,stmfd。

ARM的栈顶指针使用的是r13寄存器。但是,之前说过,在不同的模式下,有各自的r13寄存器。所以说,当程序运行到其他模式的时候,如果是用C语言的话,就要设置对应模式的r13寄存器,以设定栈顶指针。目前程序都是在SVC模式下运行的,就只设置这个模式下的r13寄存器就可以了。


栈的位置是要设置在内存中的,之前初始化的ddr的地址空间是0x50000000~0x57ffffff。ARM又是满递减栈,这里就可以把栈的位置设置在0x54000000。当然这个位置可以随意设置,但是要注意栈的空间不能和程序空间重合。因为在内存中也保存的程序的代码。栈又是一直递减的,如果栈的设置不合理,就会递减到程序的空间,从而把程序给覆盖了,那么就可能程序就会运行出错了。

   clip_image004

其实,设置栈的程序很简单,就只是给r13寄存器赋个值就行了。

          clip_image005

Sp是r13寄存器的别名,表示栈指针。注意,这里设置的栈指针是给SVC模式设置的。当切换到其他模式下,是要重新设置sp的。


下面一步就是对BSS段清零了。BSS段,保存的C代码中定义的未初始化的全局变量。在连接器脚本中,有设置BSS段的起始地址,也有设置BSS段的结束地址。


BSS段有什么作用了,保存未初始化的全局变量。假设在程序中,定义了一个int a[10000]这么大的数组。但是没有对这个数组进行初始化。如果把这个变量给写到代码区的话,那么代码就会增加40000个字节大小。这无疑是不科学的。所以将这个数据放在BSS段,给出首地址和结束地址,那么就只需要8个字节就够了,节约了很大的空间。

clip_image006

就利用这起始地址和结束地址来对BSS段进行清零。


代码也是比较简单的。

clip_image007

首先判断BSS段的起始地址和结束地址是否一样,一样的话,说明目前没有BSS段数据,那么就没有必要清零,直接返回。程序中用的就是movep,带条件判断的赋值指令。不一样的话,说明BSS段有数据,那么就对这一片空间进行清零就可以了。


这样,C语言的环境就初始化完毕了。也就是设置栈指针,以及对BSS段清零。


对比STM32,

在启动代码的最后,有如下代码:

         clip_image009

         这段代码对堆栈进行初始化。栈是用来程序跳转的时候使用,堆是动态分配内存的时候用的。

         目前,我还没有找到这段代码是在什么地方调用的。查阅网上资料,说是在_main函数中有进行调用。但是在调用_main函数之前,就已经调用了一个c函数进行系统的初始化。而c函数在执行之前,是需要栈的啊。

clip_image010


 

这个问题的话,就要说起STM32的复位启动了。以下是cortex-M3权威手册中说的。

clip_image012

 MSP,是主堆栈的意思。在STM32中有两个堆栈,这里就先不管这个,就认为这个MSP是堆栈就好了。

 0地址处的值就是堆栈的地址。所以CM3先从0地址处取出堆栈的地址,赋值给sp。这样,就有了堆栈指针,剩下调用c函数就没有问题了。然后再取出0x4的值,这个是复位的跳转地址,然后程序跳转到这个地址去,执行复位代码。

clip_image013clip_image014 


上图是软件仿真看的反汇编代码及执行到reset的第一条代码的各个寄存器值。0地址处的值是0x0418。STM32的内存空间是从0x20000000开始的,这个就是偏移。所以sp的值就是0x20000418。寄存器列表中的sp也是这个值。这个418是怎么来的,目前我还没有搞懂,但是程序大小不一样,这个值就会不一样。


这样的话,栈就设置好了,就可以进行c函数的调用了。后面在_main函数中,又调用了启动代码最后的堆栈初始化的代码。

推荐阅读

史海拾趣

High Voltage Semiconductor Inc公司的发展小趣事

为了更好地服务全球客户,美高测积极寻求与国际知名企业的合作。通过与半导体制造巨头台积电、英特尔等公司的合作,美高测不仅获得了先进的制造技术和市场洞察能力,还成功将其高压测试产品打入了这些巨头的供应链体系。同时,公司还与多个国家的科研机构建立了长期合作关系,共同开展前沿技术的研发和应用,进一步提升了公司的国际影响力。

固驰(GUERTE)公司的发展小趣事

浙江固驰电子有限公司,即固驰(GUERTE)品牌的发源地,于1995年在浙江省丽水市创立。公司由范*先生创立,初期专注于半导体器件的生产。经过数年的不懈努力,固驰电子逐渐在行业内崭露头角,通过持续的技术创新和产品优化,成功开发出ZQ系列整流管芯、CELL芯片、5-200A单三相整流桥及电力半导体模块等核心产品。这些产品广泛应用于变频器、逆变焊机、UPS电源等领域,为公司的快速发展奠定了坚实基础。

ASC Capacitors公司的发展小趣事

ASC Capacitors的创始人,凭借对电子行业的深厚情感和对电容技术的独到见解,于XXXX年创立了这家公司。他们深知电容在电子行业中的重要性,因此立志要打造一家专业制造高质量电容器的企业。从最初的几间厂房和几名员工,ASC Capacitors凭借坚韧不拔的精神和对技术的执着追求,逐渐在电子行业中崭露头角。

Dau Semiconductor Inc公司的发展小趣事

随着全球电子市场的不断发展壮大,Dau Semiconductor Inc公司开始将目光投向全球市场。公司积极开拓海外市场,与全球各地的电子产品制造商建立合作关系。同时,公司还加强了与国际知名半导体企业的合作与交流,共同推动半导体技术的发展和应用。展望未来,Dau Semiconductor Inc公司将继续秉承创新、卓越、服务的企业精神,为全球电子行业的发展做出更大的贡献。

ASSMANN WSW components公司的发展小趣事

ASSMANN WSW components公司一直致力于技术创新和产品研发。在某个关键时刻,公司研发团队成功开发出了一种具有革命性的新型连接器,这种连接器不仅性能稳定、寿命长,而且具有极高的可靠性和安全性。这一技术突破使得ASSMANN WSW在电子元件市场上脱颖而出,迅速成为行业内的佼佼者。

Hei Inc Optoelectronic Division公司的发展小趣事
定期对控制电路进行检查和维护,及时发现并处理潜在问题,以确保设备的长期稳定运行。

问答坊 | AI 解惑

用电阻做功率模拟

请教各位,我现在测一块散热板的散热效率,打算用铜壳线绕电阻做一个30W的发热源,电阻型号有以下几款 220Ω/5W;500Ω/8W;输入电压在60V左右,请问应该怎样排列电阻效果才好?谢谢!…

查看全部问答>

闪电击中世界最高建筑哈利法塔

上面这张令人震惊的照片展示了世界最高建筑哈利法塔遭闪电击中时的场面。 照片的拍摄者是一位23岁名叫穆罕默德·哈姆丹的学生,来自巴基斯坦,目前在阿联酋攻读建筑工程学。当时,迪拜正遭受暴风雨的袭击。雷电中,高达828米的哈利法塔在紫色的 ...…

查看全部问答>

今天参加mcu day赠送的一款开发板

参加TI mcu Day时,送的开发板,据说可以当做jtag仿真器使用,双重功能!!!…

查看全部问答>

U盘多盘符的问题

我在一个嵌入式系统中,主机在GET MAX LUN我已经返回01,但是主机并未显示2个盘符.仅仅出现了一个盘符 还需要做哪方面的工作…

查看全部问答>

关于桥式整流

这是在空闲之际模拟的几张桥式整流和接电容的图片,希望能对大家有点用处。    大家注意看波形随着电容的变化而变化。…

查看全部问答>

hmc5883的程序有人做过么?我的程序哪里出问题了?本人菜鸟,见笑了。

调了好几个小时了,就是不知道问题在哪里,请高手们指点。 测量先不说,就是怎么读寄存器都没弄清。 看了中文的pdf了,但是还是没搞懂,先看看我的程序吧。 程序部分(已近将无关部分删除): uchar code table[]=\"0123456789\"; //////////// ...…

查看全部问答>

有谁用了ADS8332,求程序!

最近用到团购买回来的ADS8332,但是调试了两天没成功,求助各位!谢谢!…

查看全部问答>

debug正常,51运算错误

已经用其他程序试验过了,不是xdata的问题,xdata里的数据能正常使用。我在用51做一个32点的fft。 部分代码如下: #include #include #define  uchar  unsigned  char #define  uint unsigned int ...…

查看全部问答>

谁用单片机驱动过PS2的数字小键盘?

我在网上买了一块PS2的数字小键盘,就是传统台式机键盘最右边的数字键部分。 学习了一下PS2及扫描编码相关内容,看懂了程序,但是,由于小键盘只有部分按键,有的键还是不能读取。 0—9数字键是可以输入的,小键盘的enter也能读取,但+、-、*、/ ...…

查看全部问答>