前言:
函数在编程中的重要性不言而喻。函数三要素,函数参数以及局部变量存在于栈上,局部变量定义需要初始化等,这些所谓的函数特征都熟背于心,时刻指导着我们设计函数。但这背后的原理是什么呢?底层的技术又是怎么实现?接下来将解开函数调用的神秘面纱!
1 栈帧(Stack Frame)
从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数返回地址。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。这里也说明了只含有局部变量(无全局或静态变量)的函数,是可重入的,因为每次调用的栈帧是独立的。
在ARM处理器中,寄存器R11(fp)指向当前的栈帧的底部(高地址),寄存器R13(sp)指向当前的栈帧的顶部(低地址)。
2 ARM指令集(Instruction-Set)
汇编指令,粗略看来有两种,分别用于CPU内部的寄存器之间的数据传递以及寄存器和CPU外部的内存之间的数据传递,前者速度快于后者。
也就是说,CPU处理数据的来源是寄存器,而寄存器的数据来源可以是寄存器,也可以是内存。也就有了不同的汇编指令:
寄存器之间的数据传递(部分指令截取):

寄存器和内存之间的数据传递:
STR(store register to a virtual address in memory):将寄存器中的数据存储到内存中
LDR(load a single value from a virtual address in memory):将内存中的数据存储至寄存器
3 函数调用过程的汇编代码分析
有了前面1,2节的理解,就可以着手分析函数的汇编代码。
编译器为: arm-none-eabi-gcc
先看源文件(test.c)
#include <stdio.h>
#define MAX 100
int fun_c

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



