其中,可写的静态数据区可以进一步分为初始化的、零初始化、未初始化的数据区。除了栈,其他部分不必占用连续的内存地址。一个程序必须有栈和代码区,其他部分不是必须的。
堆是一段由进程自己管理的内存区域,比如在C中通过malloc分配的空间就在堆上。堆常用于动态创建数据对象。
程序只能执行位于代码段的指令。
3.2.1 栈栈用来保存局部变量和传递参数,当参数寄存器不够用时就是通过栈来传递参数的。
栈被设计为向下增长的,即栈顶在最低地址,栈顶的位置保存在寄存器SP中。一般情况下,栈有一个基地址base和一个栈大小限制limit。栈可以用固定的大小,或者是动态变化的(通过调整limit来实现)。
栈的一些规则:
栈指针在基地址与栈限制之间, stack_limit < SP <= stack_base
SP mod 4 = 0, 栈地址保持4字节对齐
程序只能访问闭区间[SP, stack_base-1]的栈内存范围
3.3 子程序调用ARM指令集中的BL指令表示带链接寄存器的跳转,当执行 BL 指令时,会把PC中下一条指令地址存到LR寄存器中,然后将跳转的目的地址存到PC中。跳转到r4中地址的代码可以用如下的指令实现,其效果等效于 BL r4。
MOV LR, PC BX r4 3.4 结果返回返回的方式取决于返回结果的类型:
半精度浮点类型占2个字节,返回在r0的低16位
小于四个字节的数据类型返回到r0中,但是做了0扩展或是符号扩展
四个字节的数据类型,直接返回到r0中
双字的类型返回到r0和r1中
128位的类型返回到 r0~r3中
小于等于四个字节的复合类型返回到r0中。
大于四个字节的复合类型,存在内存中,内存的地址是通过参数传进子函数的。
3.5 参数传递程序调用通过寄出去你r0-r3和栈来传递参数,参数较少时便用不到栈。
参数传递被定义为两层概念模型:
一种从源码语言参数到机器类型的映射 A mapping from a source language argument onto a machine type
整理机器类型来产生最终的参数列表 The marshalling of machine types to produce the final parameter list