《coredump问题原理探究》Linux x86版3.3节栈布局之局部变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/details/8514990

在上一节已经探讨了空函数时的栈布局,那么,在程序运行时,会有一些局部变量,那么它们是存放在栈哪里?在这里,继续探究一下当函数有局部变量时栈是怎样布局的。

先看例子:

int func()
{
     int a = 0x12345678;
 
     int *p = &a;
 
     return *p;
}
 
int main()
{
     int b = 0x87654321;

     return b + func();
} 

编译它

[buckxu@xuzhina 2]$ cc -o xuzhina_dump_c3_s2 xuzhina_dump_c3_s2.cpp

看一下main函数的汇编:

(gdb) disassemble main
Dump of assembler code for function main:
   0x080483ea <+0>:     push   %ebp
   0x080483eb <+1>:     mov    %esp,%ebp
   0x080483ed <+3>:     sub    $0x10,%esp
   0x080483f0 <+6>:     movl   $0x87654321,-0x4(%ebp)
   0x080483f7 <+13>:    call   0x80483d0 <_Z4funcv>
   0x080483fc <+18>:    mov    -0x4(%ebp),%edx
   0x080483ff <+21>:    add    %edx,%eax
   0x08048401 <+23>:    leave  
   0x08048402 <+24>:    ret    
End of assembler dump.

由于在main函数里,只有一个局部变量b,它的值是0x87654321,从指令

   0x080483f0 <+6>:     movl   $0x87654321,-0x4(%ebp)

可以知道

在main函数这一桢里,ebp-4所指向的单元存放着局部变量b。在0x080483f7打断点,看一下是不是这样:

(gdb) i r ebp 
ebp            0xbffff4d8       0xbffff4d8
(gdb) x /4x $ebp-4    
0xbffff4d4:     0x87654321      0x00000000      0x4a8bf635      0x00000001
(gdb) info symbol 0x4a8bf635
__libc_start_main + 245 in section .text of /lib/libc.so.6

确实如此,且紧挨着ebp所指向的单元。

再看一下func函数的汇编:

(gdb) disassemble func
Dump of assembler code for function _Z4funcv:
   0x080483d0 <+0>:     push   %ebp
   0x080483d1 <+1>:     mov    %esp,%ebp
   0x080483d3 <+3>:     sub    $0x10,%esp
   0x080483d6 <+6>:     movl   $0x12345678,-0x8(%ebp)
   0x080483dd <+13>:    lea    -0x8(%ebp),%eax
   0x080483e0 <+16>:    mov    %eax,-0x4(%ebp)
   0x080483e3 <+19>:    mov    -0x4(%ebp),%eax
   0x080483e6 <+22>:    mov    (%eax),%eax
   0x080483e8 <+24>:    leave  
   0x080483e9 <+25>:    ret    
End of assembler dump.

由于func有两个局部变量,一个是a,值为0x12345678,一个是p,初始化为&a.

   0x080483d6 <+6>:     movl   $0x12345678,-0x8(%ebp)

可以知道ebp-8指向局部变量a。

   0x080483dd <+13>:    lea    -0x8(%ebp),%eax
   0x080483e0 <+16>:    mov    %eax,-0x4(%ebp)

可知,ebp-4指向局部变量p。

在  

 0x080483e3 <+19>:    mov    -0x4(%ebp),%eax

处打断点,可以看到如下内容:

(gdb) tbreak *0x080483e3
Temporary breakpoint 2 at 0x80483e3
(gdb) c
Continuing.

Temporary breakpoint 2, 0x080483e3 in func() ()
(gdb) i r ebp
ebp            0xbffff4c0       0xbffff4c0
(gdb) x /4x $ebp-8
0xbffff4b8:     0x12345678      0xbffff4b8      0xbffff4d8      0x080483fc

果然,ebp-8放着0x12345678,而ebp-4则放着ebp-8,即0xbffff4b8。

从这两个函数的情况,可以看出局部变量在栈上的布局是这样的,如图:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Go 语言简介(上)— 语法

Hello World package main //声明本文件的package名 import "fmt" //import语言的fmt库——用于输出 f...

4048
来自专栏LIN_ZONE

javascript基础重点

1.在javascript中使用 == 比较,会自动转换数据类型再比较,有时候会 得到非常诡异的结果;一般情况下使用 === 比较,它不会自动转换数据类型,如果...

962
来自专栏Python爬虫实战

Python数据类型之字符串

字符串就是一系列的字符。Python中,用配对的引号括起来的都是字符串,其中引号可以是单引号也可以是双引号:

882
来自专栏我的小碗汤

go语言正则表达式

我们前两节课爬取珍爱网的时候,用到了很多正则表达式去匹配城市列表、城市、用户信息,其实除了正则表达式去匹配,还可以利用goquery和xpath第三方库匹配有用...

1324
来自专栏Pythonista

Python3编程技巧

Microsoft Excel是Microsoft为使用Windows和Apple Macintosh操作系统的计算机编写的一款电子表格软件。直观的界面、出色的...

1092
来自专栏Golang语言社区

【Go 语言社区】Golang源码解读之map

golang的map实现并不是像c++一样使用红黑树,而是使用了hashmap,用数组来实现。 详细的实现后续补充,这里先做个备忘。 在iterate整个map...

3083
来自专栏LEo的网络日志

go语言接口学习

3695
来自专栏PHP在线

AJAX传递特殊字符的方法

AJAX传递特殊字符的方法 采用Ajax传递参数加号(+)和与符号(&)时候,服务端获取到的参数并不如意! (1) "+"号:JavaScript解析为字符串连...

3708
来自专栏TungHsu

这或许是对小白最友好的python入门了吧——6,删除列表元素

这个时候我们CET考完了,怎么才能把它删除呢。这时候我们可以用del这个函数,用法如下: del exam[0] print(exam) #print的作用...

3708
来自专栏张善友的专栏

深入浅出事件流处理NEsper(二)

NEsper使用的事件类型来描述事件的类型信息。你的应用在启动时可能预先配置定义事件类型,或者在运行时通过API或EPL语法动态的增加事件类型。 EPL中的cr...

20110

扫码关注云+社区

领取腾讯云代金券