一个简单的C程序源码
一、第一步
1、将cpu寄存器的值push到栈中
2、lr是r14寄存器
二、第二步
1、CPU内部使r0寄存器的值 = 1;
2、将r0寄存器的值存入栈中的sp+4的位置
3、对应着 int a = 1;
三、第三步
1、把数值2放到CPU的r0寄存器,故CPU寄存器的r0 = 2;
2、把r0寄存器的值存入栈中sp+0的位置
3、对应着int b = 2;
四、第四步
1、将sp的值存入CPU的r1寄存器,也就是把变量b的地址存入r1
2、r0 = sp+4,也就是把变量a的地址存入r0中
3、BL.W, Branch With LinK的缩写,BL.W指令用于将程序的控制权转移到指定的地址,并且在跳转之前,将下一条指令的地址保存在ARM处理器中LR寄存器。因此,BL.W指令不仅可以实现跳转功能,还可以在跳转之后方便地返回到原来的位置。
4、将下一条指令的地址存入CPU的LR寄存器,下一条指令是return 0;也就是把0x0800015E 存入LR寄存器
5、跳转到add_val函数进行执行,也就是将程序控制权转移到地址0x08000138
五、第五步
1、由上一步可知,程序跳转到地址 0x08000138继续执行
2、将CPU的 r3 和 lr 寄存器的值push到栈中,高地址保存在高地址中,入栈过程中sp会自减,sp = sp - 4;
3、而lr寄存器我们在第四步的时候函数跳转前把“return 0”的地址也就是0x0800015E 存入进去,而现在我们把该地址push入栈就是为了保存该返回地址,以便在当下函数执行完后能够跳转回去。
六、第六步
1、寄存器 r2 从r0 + 0的寄存器里所存放的地址所指向的值读取数据,而r0寄存器里存放的是变量a的地址,故把1读到了 r2 寄存器里去
2、把寄存器 r2 的值存入sp + 0的位置,也就是栈中r3的位置
七、第七步
1、把 r1 寄存器所存放的地址所指向的值(也就是b的地址,而b的值是2)存入r2中,故CPU寄存器中 r2 = 2.
2、把 sp + 0 的位置的值存入 r3 中,也就是把1存入CPU寄存器r3.
3、r2 = r2 + r3,CPU对r2,r3寄存器中的值进行了计算,而后又存入r2.
4、CPU把r2寄存器中的值保存进栈中的sp + 0的位置
八、第八步
1、把sp地址里存放的值又读入r2寄存器
2、向 r2 寄存器存入r0寄存器所存放的地址,而 r0 寄存器里所存放的地址就是变量a在栈中的地址
九、第九步
1、r3 = sp,
2、sp = sp + 4,
3、pc = sp,
4、sp = sp + 4,
5、目的是把栈中存放的 LR 返回地址写入 CPU 的 PC 寄存器,以便 CPU 能够找到返回的地址继续执行代码
十、第十步
1、代码执行将会跳到LR所指向的地址位置,也就是0X0800015E ,把 0 存入CPU的 r0 寄存器中