局部变量申请栈空间时的入栈顺序
2016-05-27 23:01
232 查看
转自 https://segmentfault.com/a/1190000002630697
运行环境:ubuntu 14.04(32bit)
编译环境:gcc
- 第一组对比:在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
局部变量在源代码中是:
char buffer_one[8], buffer_two[8];
int value = 5;
栈溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:buffer_two,buffer_one,value;
没有溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:buffer_one,buffer_two,value;
- 第二组对比:调整局部变量的顺序,再次在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
即源码中局部变量声明改为:
int value = 5;
char buffer_one[8], buffer_two[8];
栈溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:buffer_two,buffer_one,value;
没有溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:value,buffer_one,buffer_two;
- 第三组对比:调整局部变量中buffer_one,buffer_two的顺序,再次在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
即源码中局部变量声明改为:
int value = 5;
char buffer_two[8], buffer_one[8];
栈溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:buffer_one,buffer_two,value;
没有溢出保护机制下的编译:
可以看出来为变量创建创建的栈顺序依次是:value,buffer_two,buffer_one;
得出的结论:
在没有溢出保护机制下的编译时,我们可以发现,所有的局部变量入栈的顺序(准确来说是系统为局部变量申请内存中栈空间的顺序)是正向的,即哪个变量先申明哪个变量就先得到空间,
也就是说,编译器给变量空间的申请是直接按照变量申请顺序执行的。
在有溢出保护机制下的编译时,情况有了顺序上的变化,对于每一种类型的变量来说,栈空间申请的顺序都与源代码中相反,即哪个变量在源代码中先出现则后申请空间;而对不同的变量来说,申请的顺序也不同,有例子可以看出,int型总是在char的buf型之后申请,不管源代码中的顺序如何(这应该来源于编译器在进行溢出保护时设下的规定)。
运行环境:ubuntu 14.04(32bit)
编译环境:gcc
Source Code: {stack_test.c} #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char buffer_one[8], buffer_two[8]; int value = 5; strcpy(buffer_one, "one"); strcpy(buffer_two, "two"); printf("[BEFORE] buffer_two is at %p and contains \'%s\'\n", buffer_two, buffer_two); printf("[BEFORE] buffer_one is at %p and contains \'%s\'\n", buffer_one, buffer_one); printf("[BEFORE] value is at %p and is %d (0x%08x)\n\n", &value, value, value); return 0; }
- 第一组对比:在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
局部变量在源代码中是:
char buffer_one[8], buffer_two[8];
int value = 5;
栈溢出保护机制下的编译:
$ gcc -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbfa12fb4 and contains 'two' [BEFORE] buffer_one is at 0xbfa12fac and contains 'one' [BEFORE] value is at 0xbfa12fa8 and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:buffer_two,buffer_one,value;
没有溢出保护机制下的编译:
$ gcc -fno-stack-protector -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbf9a1530 and contains 'two' [BEFORE] buffer_one is at 0xbf9a1538 and contains 'one' [BEFORE] value is at 0xbf9a152c and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:buffer_one,buffer_two,value;
- 第二组对比:调整局部变量的顺序,再次在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
即源码中局部变量声明改为:
int value = 5;
char buffer_one[8], buffer_two[8];
栈溢出保护机制下的编译:
$ gcc -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbfe0ac54 and contains 'two' [BEFORE] buffer_one is at 0xbfe0ac4c and contains 'one' [BEFORE] value is at 0xbfe0ac48 and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:buffer_two,buffer_one,value;
没有溢出保护机制下的编译:
$ gcc -fno-stack-protector -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbf9998bc and contains 'two' [BEFORE] buffer_one is at 0xbf9998c4 and contains 'one' [BEFORE] value is at 0xbf9998cc and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:value,buffer_one,buffer_two;
- 第三组对比:调整局部变量中buffer_one,buffer_two的顺序,再次在栈溢出保护机制下的编译和没有溢出保护机制下的编译的入栈顺序的对比:
即源码中局部变量声明改为:
int value = 5;
char buffer_two[8], buffer_one[8];
栈溢出保护机制下的编译:
$ gcc -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbff96dfc and contains 'two' [BEFORE] buffer_one is at 0xbff96e04 and contains 'one' [BEFORE] value is at 0xbff96df8 and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:buffer_one,buffer_two,value;
没有溢出保护机制下的编译:
$ gcc -fno-stack-protector -g -o so stack_test.c $ ./so [BEFORE] buffer_two is at 0xbfa55234 and contains 'two' [BEFORE] buffer_one is at 0xbfa5522c and contains 'one' [BEFORE] value is at 0xbfa5523c and is 5 (0x00000005)
可以看出来为变量创建创建的栈顺序依次是:value,buffer_two,buffer_one;
得出的结论:
在没有溢出保护机制下的编译时,我们可以发现,所有的局部变量入栈的顺序(准确来说是系统为局部变量申请内存中栈空间的顺序)是正向的,即哪个变量先申明哪个变量就先得到空间,
也就是说,编译器给变量空间的申请是直接按照变量申请顺序执行的。
在有溢出保护机制下的编译时,情况有了顺序上的变化,对于每一种类型的变量来说,栈空间申请的顺序都与源代码中相反,即哪个变量在源代码中先出现则后申请空间;而对不同的变量来说,申请的顺序也不同,有例子可以看出,int型总是在char的buf型之后申请,不管源代码中的顺序如何(这应该来源于编译器在进行溢出保护时设下的规定)。
相关文章推荐
- iOS中的pch文件
- (C语言)自拟顺序表的各种操作
- [Mac]在 Mac 上开发 .Net 应用 c#
- Maven Archetype 简单介绍
- 1007. 素数对猜想 (20)
- 15 个 Android 通用流行框架大全
- Menu基本介绍实现
- 用c语言写的kmeans算法,不是很完善
- BZOJ_2002_弹飞绵羊_(LCT)
- POJ1068
- web.config connectionStrings 数据库连接字符串的解释(转载)
- 什么是架构
- 数组元素奇偶排序程序中的死循环引起的思考
- Ukey,网页,web demo访问U盘用户验证
- 什么是架构
- 自适应网页设计的方法
- HDU 1016 Prime Ring Problem
- 线程的五种状态
- 考研复习第四天-线性代数-矩阵的初等线性变换
- 但是安装完之后,发现ifconfig没看到熟悉的eth0,却是enp0s3,于是想把他改回来