04 局部变量的空间分配及栈回收重用之汇编分析
来源:互联网 发布:后端用java还是php 编辑:程序博客网 时间:2024/06/05 09:06
估计每个人在学C语言时被告之:当函数里的代码执行时,函数体内的局部变量会在栈里分配空间,函数执行结束时回收所分配的空间。
但具体是怎样分配,怎样的回收,这些问题就只能发挥想象力了,学会汇编后,其实我们就可以更加的直观地去了解。
对栈不熟悉的话,可以参考程序的段,堆与栈
1). 局部变量的分配空间
test.c 1 2 int main(void) 3 { 4 int a = 56, b = 77; 5 6 7 return 0; 8 } 编译后,用arm编译器的objdump工具得到汇编代码: 0000839c <main>: 839c: e52db004 push {fp} ; (str fp, [sp, #-4]!) //为调用main函数的调用者备份fp寄存器的内容,因下面需改变它的值 83a0: e28db000 add fp, sp, #0 //用fp寄存器存放栈顶最初的位置 , 函数执行时,再把fp寄存器的位置恢复到sp寄存器里,即栈回收了 83a4: e24dd00c sub sp, sp, #12 //在栈里分配空间,用于局部变量a, b. 相当于int a, b; 83a8: e3a03038 mov r3, #56 ; 0x38 83ac: e50b3008 str r3, [fp, #-8] // (fp-8)的位置即是变量a的地址,这里是给局部变量a赋值. a = 56 83b0: e3a0304d mov r3, #77 ; 0x4d 83b4: e50b300c str r3, [fp, #-12] // (fp-12)的位置即是变量b的地址, 给变量b赋值. b = 77; 83b8: e3a03000 mov r3, #0 83bc: e1a00003 mov r0, r3 //返回值放到r0 83c0: e28bd000 add sp, fp, #0 //函数结束前恢复栈顶位置. 即局部变量a,b所分配的空间被回收了. 83c4: e8bd0800 ldmfd sp!, {fp} //恢复fp寄存器的内容 83c8: e12fff1e bx lr //跳回到返回地址. mov pc, lr
2). 函数的参数也是局部变量
test.c 1 2 void func(int aa) 3 { 4 aa = 89; 5 } 6 7 int main(void) 8 { 9 10 return 0; 11 } 编译后的反汇编代码: 0000839c <func>: 839c: e52db004 push {fp} ; (str fp, [sp, #-4]!) 83a0: e28db000 add fp, sp, #0 83a4: e24dd014 sub sp, sp, #20 83a8: e50b0010 str r0, [fp, #-16] 83ac: e3a03059 mov r3, #89 ; 0x59 83b0: e50b3008 str r3, [fp, #-8] // aa = 89; 由此可见函数参数是在栈里分配空间的,也是一个局部变量来的 83b4: e28bd000 add sp, fp, #0 83b8: e8bd0800 ldmfd sp!, {fp} 83bc: e12fff1e bx lr
3). 栈回收重用的问题
test.c 1 2 #include <stdio.h> 3 4 void func2() 5 { 6 int a, b; 7 8 printf("a = %d, b = %d\n", a, b); 9 } 10 11 void func() 12 { 13 int aa = 33, bb = 44; 14 } 15 16 int main(void) 17 { 18 func(); //先执行函数func 19 func2(); //再执行函数func2 20 return 0; 21 } 程序编译后执行的输出: a = 33, b = 44; 反汇编后的代码: 000083f8 <func>: //先执行func函数 83f8: e52db004 push {fp} ; (str fp, [sp, #-4]!) 83fc: e28db000 add fp, sp, #0 //用fp寄存器记录栈顶位置 8400: e24dd00c sub sp, sp, #12 //栈分配12字节 8404: e3a03021 mov r3, #33 ; 0x21 8408: e50b3008 str r3, [fp, #-8] // func函数里的 aa = 33; 840c: e3a0302c mov r3, #44 ; 0x2c 8410: e50b300c str r3, [fp, #-12] // func函数里的 bb = 44; 8414: e28bd000 add sp, fp, #0 //栈顶位置从fp寄存器恢复, aa和bb变量的空间已回收,但原来位置上的值不变 8418: e8bd0800 ldmfd sp!, {fp} 841c: e12fff1e bx lr 000083d0 <func2>: //func函数执行后,func2函数接着执行 83d0: e92d4800 push {fp, lr} //注意,这里多压栈一个寄存器的内容 83d4: e28db004 add fp, sp, #4 //这里sp+4刚好对上 func函数里"add fp, sp, #0"语句时的栈顶位置 83d8: e24dd008 sub sp, sp, #8 83dc: e59f0010 ldr r0, [pc, #16] ; 83f4 <func2+0x24> 83e0: e51b1008 ldr r1, [fp, #-8] //这里的(fp-8)对应func函数里的(fp-8), 取出的值就是33 83e4: e51b200c ldr r2, [fp, #-12] //这里的(fp-12)对应func函数里的(fp-12), 取出的值就是44 83e8: ebffffb5 bl 82c4 <_init+0x20> //调用printf函数 83ec: e24bd004 sub sp, fp, #4 83f0: e8bd8800 pop {fp, pc} 83f4: 00008490 muleq r0, r0, r4
阅读全文
0 0
- 04 局部变量的空间分配及栈回收重用之汇编分析
- 解析C++汇编代码-局部变量空间分配及程序栈操作
- [转载]解析C++汇编代码-局部变量空间分配及程序栈操作
- 解析C++汇编代码-局部变量空间分配及程序栈操作
- 解析C++汇编代码-局部变量空间分配及程序栈操作
- 解析C++汇编代码-局部变量空间分配及程序栈操作
- 解析C++汇编代码(了解函数在堆栈中的工作流程)-局部变量空间分配及程序栈操作
- 全局变量,静态局部变量,局部变量空间的堆分配和栈分配
- 全局变量,静态局部变量,局部变量空间的堆分配和栈分配问题
- 局部变量空间分配及程序栈操作----(转,收藏)
- 汇编的局部变量
- 汇编的局部变量
- [学习小记] 从汇编角度看局部变量的分配及数组名与指针的关系
- [学习小记] 从汇编角度看局部变量的分配及数组名与指针的关系 .
- Tensorflow 变量命名空间及变量重用
- Tensorflow 变量命名空间及变量重用
- 操作系统实验之主存储器空间的分配和回收
- 局部变量的位置分配
- linux(九)软件包管理
- C++ 仓库管理系统 控制台
- android studio代理设置
- windows下安装MinGW(绿色)-路径配置
- time stamp convert tools 1.0.0.1 on vs2010
- 04 局部变量的空间分配及栈回收重用之汇编分析
- SVN的使用一:TortoiseSVN的下载安装
- cookie详解
- Git版本库相关操作
- 566. Reshape the Matrix
- HDU4909 String
- 教你如何修改wordpress模版技巧分享
- 树、森林与二叉树的转换和哈夫曼树
- 哈希表的使用-11-散列1 电话聊天狂人