局部变量的栈分配
下面我们分析一下C编译器如何处理局部变量的分配,为此先给出如下程序:
#vi test2.c
int main()
{
int i;
int j=2;
i=3;
i=++i;
return i+j;
}
编译该程序,产生二进制文件,并利用mdb来观察程序运行中的stack的状态:
#gcc test2.c -o test2
#mdb test2
Loading modules: [ libc.so.1 ]
> main::dis
main: pushl %ebp
main+1: movl %esp,%ebp ; main至main+1,创建Stack Frame
main+3: subl $8,%esp ; 为局部变量i,j分配栈空间,并保证栈16字节对齐
main+6: andl $0xf0,%esp
main+9: movl $0,%eax
main+0xe: subl %eax,%esp ; main+6至main+0xe,再次保证栈16字节对齐
main+0x10: movl $2,-8(%ebp) ; 初始化局部变量j的值为2
main+0x17: movl $3,-4(%ebp) ; 给局部变量i赋值为3
main+0x1e: leal -4(%ebp),%eax ; 将局部变量i的地址装入到EAX寄存器中
main+0x21: incl (%eax) ; i++
main+0x23: movl -8(%ebp),%eax ; 将j的值装入EAX
main+0x26: addl -4(%ebp),%eax ; i+j并将结果存入EAX,作为返回值
main+0x29: leave ; 撤销Stack Frame
main+0x2a: ret ; main函数返回
>
通过mdb对程序运行时的寄存器和栈的观察和分析,可以得出局部变量在栈中的访问和分配及释放方式:
1.局部变量的分配,可以通过esp减去所需字节数
subl $8,%esp
2.局部变量的释放,可以通过leave指令
leave
3.局部变量的访问,可以通过ebp减去偏移量
movl -8(%ebp),%eax
addl -4(%ebp),%eax
问题:当存在2个以上的局部变量时,如何进行栈对齐?
在上篇文章中,提到subl $8,%esp语句除了分配栈空间外,还有一个作用就是栈对齐。那么本例中,由于i和j正好是8字节,那么如果存在2个以上的局部变量时,如何同时满足空间分配和栈对齐呢?
关键字:汇编技术 局部变量 栈分配
引用地址:汇编技术内幕(3)
推荐阅读最新更新时间:2024-03-16 14:41
stm32局部变量过大,导致栈溢出
在做一个以stm32为主控的项目时发现自己程序中一个机构体里面的数据总是一运行就被改变,刚开始以为是自己不小心在哪个地方用了extern扩展了变量的作用域,重新赋了值, 自己忘记了,后来查找了好久都没有其他地方使用这个结构体变量,于是开始单步调试,结果进入一个函数的时候(里面定义了一个200个数据float型的数组),发现只要定了一个这个数组,这时前文提到的那个结构的值就发生改变,通过在keil软件中的Memory窗口查看结构体的变量可以清楚看到结构体的地址里面的数据在这个时候发生改变, 然后修改,这个局部变量数组的大小,把它改小之后,就没有发生问题。因为局部变量是储存在栈中的,于是猜想,这种问题应该是stm32的栈的内存的溢出造
[单片机]
labview局部变量与全局变量
之前做上位机就想拿一个停止键控制两个并行的循环,如下 那时候拿布尔里面的停止按钮做局部变量没有成功,会出现如下的错误(当时太匆忙没有解决) 现在找到解决办法了,前面板-停止控件-属性-操作-按钮动作,里面可以选择不同的触发方式,我试了下觉得保持转换直到释放用在这里比较不错。 今天还试了下全局变量(需要点击在弹出的前面板上放需要用到的变量),建好的全局变量在程序框图-函数-选择VI里面可选。可在前面板上放不同的控件(目前还没有需要,有需要时可以试试,放一个控件的试过了,还不错,不过简单的程序没必要) 不太使用全局变量的原因之一是效率低
[测试测量]
【STM32F0】Keil 查看局部变量显示
现象: 在进行STM32F0开发的时候出现了,调试代码,添加变量Watch时,显示not in scope。 处理方式: 因为代码开了优化的处理,把优化改到Level0,就可以解决问题。
[单片机]
小广播
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐
最新单片机文章
更多精选电路图
更多热门文章
更多每日新闻
更多往期活动
11月21日历史上的今天
厂商技术中心