设为首页 加入收藏

TOP

ARM架构中的程序执行与调用
2017-12-29 06:06:51 】 浏览:200
Tags:ARM 架构 程序 执行 调用

从软件视角看,内存是字节的阵列,每一个字节都是可寻址的。


下面以C语言为例,看一下结构体的对齐方式:


程序输出如下:



可以看出这是小端字节序,即数据的最低字节存放在最低地址。b的存放位置位于0x40ea2c地址处,虽然只占一个字节。但是由于成员c是8字节对齐的,c的起始地址8位对齐,所以c应该位于0x40ea30,0x40ea2d到0x40ea2f这三个字节是为了对齐而扩充的。而该结构体的对齐值为成员的最大对齐值也为8,所以最后一个成员d,虽然只占2字节,但是需要扩充的8字节对齐。


ARM架构定义了一组核心指令集和一些有协处理实现的附加指令。核心指令集可以访问核心寄存器,协处理器合一提供附加的寄存器用于某些特殊操作。


ARMv7架构中包含了16个32位寄存器,可以用R0-R15表示。下表中描述了每个寄存器的特定应用。


r0-r3四个寄存器用来向被调用程序传递参数,以及从一个函数返回结果。ARMv7中用寄存器传递参数最多可以有四个,更多的参数传递,则需要用到栈来实现。这几个寄存器也可以当做普通寄存器来存储临时值。


寄存器r12(IP)被链接器使用,在调用程序和子程序之间作为一个scratch register 。


r9寄存器功能是对应平台定义的,一个虚拟平台可以任意使用该寄存器,但要给出说明。比如,它可以作为一个静态基地址(static base, SB)在一个位置无关数据中; 或者也可以作为线程寄存器(thread register, TR)。


一个被调用程序必须保存寄存器r4-r8,r10,r11的值,因为这些值可能保存着调用程序的某些局部变量。被调用程序还必须保存SP寄存器,以在返回时恢复调用前的栈信息。


在所有的程序调用标准中,寄存器 r12-r15都有着特殊的角色,用IP、SP、IR、PC来表示。


寄存器CPSR(当前程序状态寄存器)包含以下特性:



处理器的运行模式如下所示:


AAPCS 应用于单线程执行,程序状态保存在机器寄存器及该程序可访问的内存里面。一个进程可访问的内存是可以在执行中变化的。


程序的内存可以分为以下五个部分:


其中,可写的静态数据区可以进一步分为初始化的、零初始化、未初始化的数据区。除了栈,其他部分不必占用连续的内存地址。一个程序必须有栈和代码区,其他部分不是必须的。


堆是一段由进程自己管理的内存区域,比如在C中通过malloc分配的空间就在堆上。堆常用于动态创建数据对象。


程序只能执行位于代码段的指令。


栈用来保存局部变量和传递参数,当参数寄存器不够用时就是通过栈来传递参数的。


栈被设计为向下增长的,即栈顶在最低地址,栈顶的位置保存在寄存器SP中。一般情况下,栈有一个基地址base和一个栈大小限制limit。栈可以用固定的大小,或者是动态变化的(通过调整limit来实现)。


栈的一些规则:


ARM指令集中的BL指令表示带链接寄存器的跳转,当执行 BL 指令时,会把PC中下一条指令地址存到LR寄存器中,然后将跳转的目的地址存到PC中。跳转到r4中地址的代码可以用如下的指令实现,其效果等效于 BL r4。


返回的方式取决于返回结果的类型:


程序调用通过寄出去你r0-r3和栈来传递参数,参数较少时便用不到栈。


参数传递被定义为两层概念模型:


本文参考 《Procedure Call Standard for the ARM Architecture》


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇STM32单片机是如何启动的? 下一篇STM32F4 编程手册学习

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目